更新加入 table 需要很长时间
update join table taking a very long time
我有一个 table citations
有 500 万行,包含以下信息:
Paperkey1 | Year1 | Paperkey2 | Year2
100 20
200 90
300 80
还有另一个 table pub_year
大约有 300 万行,包含以下信息:
Paperkey | Year
100 2001
200 2002
20 2003
90 2004
80 2005
我想通过从 table pub_year
中获取年份值来更新 table citations
。我使用了以下查询,但它已 运行 超过 3 小时,但仍未完成。
update citations T2
join pub_year T1 on T2.paperkey1= T1.paperkey
set T2.year1 = T1.year;
有谁知道它花费太长时间的主要原因是什么?如果我继续让它运行,我不确定它是否会完成。还是我的查询有问题?
paperkey 字段都是 varchar,year 字段都是整数。谢谢。
这是 运行 EXPLAIN:
之后的更新
第二行在第 type
列中有值 ALL
。这是执行速度非常非常慢的原因。对于 citations
的 500 万行中的每一行,它需要扫描 table pub_year
的所有 300 万行,以便为 JOIN
子句找到匹配的行。索引将解决这个问题。
在 table 的 Paperkey1
列上添加索引 citations
:
ALTER TABLE `citations` ADD INDEX (`Paperkey1`);
还在 table 的 Paperkey
列上添加索引 pub_year
:
ALTER TABLE `pub_year` ADD INDEX (`Paperkey`);
如果两个 table 中的一个已经包含上述列的索引(或者它是多列索引中的第一列),则跳过 table;具有相同的索引没有帮助。
创建索引后(它们需要一些时间才能完成,尤其是如果这些 table 上同时存在其他 activity),运行 EXPLAIN
再次检查结果。
您应该在第二行的 type
列中得到 ref
或 eq_ref
。
现在 UPDATE
会更快完成。它仍然需要几分钟(如果 tables 在查询期间被其他进程访问,则甚至需要更多时间)但是当你更新 500 万条记录时这没问题。
出于性能原因,在 INNER JOIN
上,建议首先放置在最终结果集中生成最少行数的 table。在这种情况下,table 是 pub_year
:
UPDATE pub_year T1
INNER JOIN citations T2 ON T2.paperkey1 = T1.paperkey
SET T2.year1 = T1.year
(作为旁注,MySQL 查询优化器足够聪明,可以更改查询并将 table 排序为提供最佳执行时间的顺序。您可以在问题的 EXPLAIN
查询结果中看到: table T1
(pub_year
) 首先出现。)
我有一个 table citations
有 500 万行,包含以下信息:
Paperkey1 | Year1 | Paperkey2 | Year2
100 20
200 90
300 80
还有另一个 table pub_year
大约有 300 万行,包含以下信息:
Paperkey | Year
100 2001
200 2002
20 2003
90 2004
80 2005
我想通过从 table pub_year
中获取年份值来更新 table citations
。我使用了以下查询,但它已 运行 超过 3 小时,但仍未完成。
update citations T2
join pub_year T1 on T2.paperkey1= T1.paperkey
set T2.year1 = T1.year;
有谁知道它花费太长时间的主要原因是什么?如果我继续让它运行,我不确定它是否会完成。还是我的查询有问题? paperkey 字段都是 varchar,year 字段都是整数。谢谢。
这是 运行 EXPLAIN:
之后的更新第二行在第 type
列中有值 ALL
。这是执行速度非常非常慢的原因。对于 citations
的 500 万行中的每一行,它需要扫描 table pub_year
的所有 300 万行,以便为 JOIN
子句找到匹配的行。索引将解决这个问题。
在 table 的 Paperkey1
列上添加索引 citations
:
ALTER TABLE `citations` ADD INDEX (`Paperkey1`);
还在 table 的 Paperkey
列上添加索引 pub_year
:
ALTER TABLE `pub_year` ADD INDEX (`Paperkey`);
如果两个 table 中的一个已经包含上述列的索引(或者它是多列索引中的第一列),则跳过 table;具有相同的索引没有帮助。
创建索引后(它们需要一些时间才能完成,尤其是如果这些 table 上同时存在其他 activity),运行 EXPLAIN
再次检查结果。
您应该在第二行的 type
列中得到 ref
或 eq_ref
。
现在 UPDATE
会更快完成。它仍然需要几分钟(如果 tables 在查询期间被其他进程访问,则甚至需要更多时间)但是当你更新 500 万条记录时这没问题。
出于性能原因,在 INNER JOIN
上,建议首先放置在最终结果集中生成最少行数的 table。在这种情况下,table 是 pub_year
:
UPDATE pub_year T1
INNER JOIN citations T2 ON T2.paperkey1 = T1.paperkey
SET T2.year1 = T1.year
(作为旁注,MySQL 查询优化器足够聪明,可以更改查询并将 table 排序为提供最佳执行时间的顺序。您可以在问题的 EXPLAIN
查询结果中看到: table T1
(pub_year
) 首先出现。)