【发布时间】:2011-09-21 15:11:04
【问题描述】:
我有一个包含用户数据的导入表,我需要用重复的字段值标记行,因为它们不应该被导入。
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;
f1 字段可以包含重复值。选择它们的查询有效:
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: You can't specify target table 'tasks' for update in FROM clause - 这是我之前遇到的错误。上述查询有效,但需要 0.5 秒。对于包含大约 30 个重复项的 20,000 行表。我将不得不处理更大的导入表,所以这是一个阻碍。
有什么想法可以加快速度吗?
【问题讨论】:
-
你定义了哪些索引?
-
好问题@Flimzy,只有主键。其他字段实际上是占位符,具有重复项的字段可以是其中任何一个。我应该尝试索引所有这些吗?总共有 40 个字段。
-
我用索引将 f1 更改为 varchar(2048)。现在需要 2 秒!
-
我建议为您加入的任何字段编制索引(在您的示例中为 a.f1)。我还建议查看 EXPLAIN 的输出以获取优化位置的线索。
-
从长远来看,您要处理多少行?几百万,我接受?
标签: mysql