fus*_*hia 2 mysql performance join
我有一个citations包含 500 万行的表,其中包含以下信息:
Paperkey1 | Year1 | Paperkey2 | Year2
100 20
200 90
300 80
Run Code Online (Sandbox Code Playgroud)
另一张表pub_year约有 300 万行,其中包含以下信息:
Paperkey | Year
100 2001
200 2002
20 2003
90 2004
80 2005
Run Code Online (Sandbox Code Playgroud)
citations我想通过从 table 中获取年份值来更新表pub_year。我使用了以下查询,但它已经运行了 3 个多小时,但仍未完成。
update citations T2
join pub_year T1 on T2.paperkey1= T1.paperkey
set T2.year1 = T1.year;
Run Code Online (Sandbox Code Playgroud)
有谁知道它花费太长时间的主要原因是什么?我不确定如果我继续让它运行它是否会完成。或者我的查询有问题吗?paperkey 字段全部为 varchar,year 字段全部为整数。谢谢。
这是运行 EXPLAIN 后的更新:

第二行的值位于ALL列 中type。这就是执行速度非常非常慢的原因。对于其中的 500 万行中的每一行,citations都需要扫描表的所有 300 万行pub_year,以便找到该JOIN子句的匹配行。索引可以解决这个问题。
Paperkey1在表的列上添加索引citations:
ALTER TABLE `citations` ADD INDEX (`Paperkey1`);
Run Code Online (Sandbox Code Playgroud)
Paperkey还要在表的列上添加索引pub_year:
ALTER TABLE `pub_year` ADD INDEX (`Paperkey`);
Run Code Online (Sandbox Code Playgroud)
如果两个表中的一个已经包含上述列的索引(或者它是多列索引中的第一列),则跳过该表;拥有相同的索引没有帮助。
创建索引后(它们将需要一些时间才能完成,特别是如果这些表上同时有其他活动),再次运行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
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,MySQL 查询优化器足够聪明,可以更改查询并将表按照提供最佳执行时间的顺序排列。您可以在EXPLAIN问题的查询结果中看到:表T1(pub_year)排在第一位.)