【问题标题】:Optimize performance of MySQL UPDATE query containing EXISTS优化包含 EXISTS 的 MySQL UPDATE 查询的性能
【发布时间】:2015-04-06 19:00:46
【问题描述】:

谁能给我一个提示,告诉我如何优化这个需要大约一分钟来处理的更新 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
)

我需要更新(设置保留=1)“存储”表(非常大)中当前保留=0 但它的 ID 存在于另一个表“项目”中的所有行。表“item”也很大,但没有“store”那么大。

我不是创建高效查询的专家,所以如果这只是一种完全错误的态度并且整个事情有一个简单的解决方案,请原谅我。

感谢您的任何想法。

【问题讨论】:

    标签: mysql sql-update subquery query-optimization exists


    【解决方案1】:

    它看起来像一些在相关子查询谓词的可移至外部查询。例如,相信这是等价的:

    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
                  )
    

    有关的是最佳性能,至少,我们会想对storereservation作为领先列的索引。还包括statusid列将意味着在这些条件可以从索引页进行检查,如果没有基础页面的在表中查找。 P>

    和该相关子(取决于查询),我们会希望对itemstore_id为主导的列的索引。 P>

    作为另一选项,考虑重新写入相关子查询作为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语句的讲解。我们可以得到最接近的是重写查询作为SELECT和获取上的讲解。 MySQL的5.6不支持上UPDATE语句解释的。 P>

    【讨论】:

    • 谢谢您的全面的答案 - 重写子查询作为一个联接actualy执行速度快了很多 - 而不是分钟花了短短的几秒钟!添加索引将是未来的操作更加有效。跨度>
    【解决方案2】:

    你可以尝试使用:

    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;
    

    这种情况应该会运行得更快,因为当您需要检查“存储”行时,您不会每次都遍历所有“项目”表。

    【讨论】:

    • 谢谢!此查询的执行速度比使用存在快得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-26
    • 2020-08-06
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多