【发布时间】:2016-11-25 21:10:53
【问题描述】:
我们在一个表中有超过 2000 万条记录,我们尝试更新 3K 条记录,但花费了 7 多分钟并且没有完成,因此终止了查询。
示例查询,
UPDATE TABLE_A
SET STATUS = 'PENDING'
WHERE ID IN (
SELECT ID
FROM TMP_TABLE_A_STATUS_FIX
); /*took more than 7 mins and didn't complete even after that*/
我们在临时表 TMP_TABLE_A_STATUS_FIX(只有 3K 条记录)中收集了所有需要更新的 id。
由于上述查询耗时过长,我们单独更新如下,
UPDATE TABLE_A SET STATUS = 'PENDING' WHERE ID = 1;
UPDATE TABLE_A SET STATUS = 'PENDING' WHERE ID = 2;
UPDATE TABLE_A SET STATUS = 'PENDING' WHERE ID = 3;
.
.
.
UPDATE TABLE_A SET STATUS = 'PENDING' WHERE ID = 2999;
UPDATE TABLE_A SET STATUS = 'PENDING' WHERE ID = 3000; /*updated all 3K recordds in 0.00 secs*/
我真的不明白IN 查询有什么问题。
有人可以解释在 where 子句中包含 INin 的更新中有什么问题以及为什么即使在 7 分钟后也没有完成?
注意 - TABLE_A 中的 ID 是主键和它的索引。 TABLE_A 中的 STATUS 也被索引。我们删除了 STATUS 的索引,因为我们认为更新索引列可能会由于索引重组而需要一些时间,但这并没有帮助。
【问题讨论】:
-
ID 列有索引吗?没有大量记录的索引表由于大量的 IO 操作来过滤受影响的记录需要太多时间。
-
@Adil,是的,我们确实有索引,更新了问题。
-
我的猜测是,在每个
UPDATE调用中,您的查询会检查它当前检查的ID是否与TMP_TABLE_A_STATUS_FIX表中的ID匹配,它通过检查每个 @TMP_TABLE_A_STATUS_FIX表中的 987654330@。那是 3k * 300 万次操作。 -
IN 是一个已识别的数据库,如果我们从数据库中处理大量数据,则需要很长时间才能处理,请使用其他方式,例如存在..
-
此处讨论了类似问题:stackoverflow.com/questions/5018284/…
标签: mysql sql database relational-database