如何解决复杂的mysql更新查询速度很慢
| 我有一个包含用户数据的导入表,我需要用重复的字段值标记行,因为它们不应被导入。CREATE TABLE `import` (
ID int(10) unsigned NOT NULL AUTO_INCREMENT,method varchar(20) DEFAULT NULL,f1 text,f2 text,PRIMARY KEY (ID)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
字段“ 1”可以保存重复值。选择它们的查询有效:
SELECT id,a.f1 FROM import a INNER JOIN
(
SELECT f1 FROM import
WHERE f1 IS NOT NULL AND f1 != \'\'
GROUP BY f1
HAVING COUNT(id) > 1
) b
ON a.f1 = b.f1
问题是要执行更新的外部查询。这是整个shebang:
UPDATE import SET method = \'ERR_DUPLICATE\' WHERE import.id IN
(
SELECT id FROM
(
SELECT id,a.f1 FROM import a INNER JOIN
(
SELECT f1 FROM import
WHERE f1 IS NOT NULL AND f1 != \'\'
GROUP BY f1
HAVING COUNT(id) > 1
) b
ON a.f1 = b.f1
) c
)
这种构造来自MySQL:您无法在FROM子句中指定目标表“任务”来进行更新-这是我之前遇到的错误。上面的查询有效,但是需要0.5秒。包含约30个重复项的20,000行表。我将不得不处理更大的导入表,所以这是一个秀场停止者。
有什么想法可以加快速度吗?
解决方法
试试这个修改后的版本:
CREATE TEMPORARY TABLE duplicate_ids
SELECT MAX(id) AS id FROM import
WHERE f1 IS NOT NULL AND f1 != \'\'
GROUP BY f1 ORDER BY NULL
HAVING COUNT(*) > 1;
UPDATE import SET method = \'ERR_DUPLICATE\' WHERE import.id IN(
SELECT id FROM duplicate_ids
);
这将为您提供更大的ID记录作为重复记录。 ORDER BY NULL禁止归因于分组的隐式排序。
此外,由于条件和使用TEXT列的分组效率低下,因此您可以维护一个额外的列,其中将包含f1中文本的哈希码。
ALTER TABLE import ADD COLUMN f1_hash INT UNSIGNED NOT NULL;
ALTER TABLE import ADD KEY(f1_hash);
f1_hash填充了CRC32(f1)(http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_crc32)返回的值。
CRC32可能有冲突,因此您最终必须检查f1列。
CREATE TEMPORARY TABLE duplicate_ids
SELECT i2.id FROM import i1 JOIN import i2
ON i2.id<>i1.id AND i1.f1_hash = i2.f2_hash
AND i1.f1_hash > 0 WHERE i1.f1 = i2.f1
然后像以前一样执行UPDATE。
您当然不需要f1列上的INDEX,所以最好将其删除,因为它会增加不必要的开销。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。