优化包含 EXISTS 的 MySQL UPDATE 查询的性能

Optimize performance of MySQL UPDATE query containing EXISTS

任何人都可以给我一些关于如何优化这个更新 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" table(非常大)中当前有 reservation=0 但其 ID 存在于另一个 [=25] 中的所有行=] "item"。 Table "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 作为前导列。还包括 statusid 列将意味着可以从索引页面检查这些条件,而无需在 table.

中查找基础页面

对于那个相关的子查询(依赖查询),我们需要 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。

您可以尝试使用:

UPDATE store s INNER JOIN item i ON s.id=i.store_id SET reservation=1 WHERE i.store_id!=0 AND s.reservation=0 AND s.status != 9;

这种情况应该会更快,因为当您需要检查 'store' 行时,您不会每次都检查所有 'item' table。