任何人都可以给我一个关于如何优化这个需要大约一分钟处理的更新 MySQL 查询的提示吗?
UPDATE store s
SET reservation=1
WHERE EXISTS (
SELECT 1
FROM item i
WHERE s.reservation=0
AND s.status!=9
AND s.id=i.store_id
AND i.store_id!=0
)
我需要更新(设置reservation=1)“store”表(非常大)中的所有行,其中当前reservation=0,但它的id存在于另一个表“item”中。表“item”也很大,但没有“store”那么大。
我不是创建高效查询的专家,所以如果这只是一种完全错误的态度并且整个问题有一个简单的解决方案,请原谅我。
感谢您的任何想法。
最佳答案
看起来相关子查询中的一些谓词可以移动到外部查询。例如,我认为这是等效的:
UPDATE store s
SET s.reservation = 1
WHERE s.reservation = 0
AND s.status != 9
AND s.id != 0
AND EXISTS ( SELECT 1
FROM item i
WHERE i.store_id = s.id
)
为了获得最佳性能,我们至少需要在 store
上建立一个以 reservation
作为前导列的索引。还包括 status
和 id
列意味着可以从索引页检查这些条件,而无需查找表中的基础页面。
对于相关子查询(相关查询),我们希望在 item
上建立一个索引,并以 store_id
作为前导列。
作为另一种选择,考虑将相关子查询重写为 JOIN 操作,例如:
UPDATE store s
JOIN item i
ON i.store_id = s.id
SET s.reservation = 1
WHERE s.reservation = 0
AND s.status != 9
AND s.id != 0
如果您运行的是 MySQL 5.5 或更早版本,则无法在 UPDATE 语句上获得 EXPLAIN。我们能得到的最接近的是将查询重写为 SELECT,并对其进行解释。 MySQL 5.6 确实支持 UPDATE 语句上的 EXPLAIN。
关于mysql - 优化包含 EXISTS 的 MySQL UPDATE 查询的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29477760/