更新连接表需要很长时间

时间:2015-01-12 11:02:20

标签: mysql performance jointable

我有一个包含500万行的表citations,其中包含以下信息:

Paperkey1 | Year1 | Paperkey2 | Year2 
100                   20
200                   90
300                   80

另一个表pub_year,包含大约300万行,其中包含以下信息:

Paperkey | Year
100        2001
200        2002
20         2003
90         2004
80         2005

我想通过从表citations获取年份值来更新表pub_year。我使用了以下查询,但它已运行超过3个小时仍然尚未完成。

update citations T2

join pub_year T1 on T2.paperkey1= T1.paperkey

set T2.year1 = T1.year;

有谁知道它花了太长时间的主要原因是什么?如果我继续让它运行,我不确定它是否会完成。或者我的查询有问题吗? paperkey字段全部在varchar中,year字段都是整数。谢谢。

以下是运行EXPLAIN后的更新:

enter image description here

1 个答案:

答案 0 :(得分:3)

ALL列中第二行的值为type。这是非常非常慢的执行的原因。对于来自citations的500万行中的每一行,它需要扫描表pub_year的所有300万行,以便找到JOIN子句的匹配行。索引将解决这个问题。

在表Paperkey1的列citations上添加索引:

ALTER TABLE `citations` ADD INDEX (`Paperkey1`);

还在表Paperkey的列pub_year上添加索引:

ALTER TABLE `pub_year` ADD INDEX (`Paperkey`);

如果两个表中的一个已经包含上述列的索引(或者它是多列索引中的第一列),则跳过该表;具有相同的索引并没有帮助。

创建索引后(它们将花费一些时间来完成,特别是如果同时在这些表上有其他活动),再次运行EXPLAIN并检查结果。 您应该在第二行的ref列中获得eq_reftype

现在UPDATE将更快完成。它仍然需要几分钟(如果在查询期间其他进程访问表,则会更多),但是当您更新500万条记录时,这是正常的。

出于性能原因,在INNER JOIN上建议首先放置在最终结果集中产生最小行数的表。在这种情况下,该表格为pub_year

UPDATE pub_year T1
INNER JOIN citations T2 ON T2.paperkey1 = T1.paperkey
SET T2.year1 = T1.year

(作为旁注,MySQL查询优化器足够聪明,可以更改查询并将表放在提供最佳执行时间的顺序中。您可以在{{1}的结果中看到来自问题的查询:表EXPLAINT1)排在第一位。)