MySQL 大表更新查询性能缓慢

问题描述 投票:0回答:1

我正在开发一个 MySQL 过程,该过程对包含超过 25,000 条记录的 Products 表执行更新。该过程运行(通常锁定)非常慢,我需要帮助优化它以获得更好的性能。

问题: 该过程根据与 TemporaryProducts 表的比较来更新 Products 表中的 IsActiveIsDeleted 字段。具体来说,它执行以下操作:

在 Products 表中查找其 Name 字段在 TemporaryProducts 表的 StoreType 字段中不存在的产品。 为产品表中的这些产品设置 IsActive = 0IsDeleted = 1

这是当前程序:

BEGIN
    UPDATE Products 
    SET IsActive = 0, IsDeleted = 1
    WHERE Name NOT IN (SELECT StoreType FROM TemporaryProducts)
    AND IsActive = 1 AND IsDeleted = 0;
END;

表结构 产品表:

  1. 超过25,000条记录
  2. 相关专栏:
  • 名称:VARCHAR(255)
  • 处于活动状态:TINYINT
  • 已删除:TINYINT

临时产品表:

  1. 超过25,000条记录
  2. 相关专栏:
  • 存储类型:VARCHAR(255)

我尝试过的:

索引:

为两个表中的相关字段添加索引:

产品:(名称、IsActive、IsDeleted)

临时产品:(商店类型)

用 LEFT JOIN 替换 NOT IN: 我尝试使用

LEFT JOIN
重写查询,如下所示:

UPDATE Products p
LEFT JOIN TemporaryProducts t ON p.Name = t.StoreType
SET p.IsActive = 0, p.IsDeleted = 1
WHERE t.StoreType IS NULL
AND p.IsActive = 1 AND p.IsDeleted = 0;

我的问题:

  1. 我还可以使用哪些其他策略来优化此更新查询以获得更好的性能?

  2. 即使添加了索引,哪些潜在瓶颈会导致查询运行缓慢?

任何指导或建议将不胜感激。 预先感谢您!

mysql stored-procedures query-optimization
1个回答
0
投票

有两件事你可以尝试让这项工作变得更好。

  1. Products (IsActive, IsDeleted, Name)
    上添加索引。这些列与您已有的复合索引相同,但最后是
    Name
    。这可能比您拥有的索引更好地支持您的 WHERE 子句。

  2. 在 UPDATE 查询中放入 LIMIT 100 或类似的值。然后循环重复,直到 ROW_COUNT() 为零。这将减少单个查询的大小,并使每个查询占用的时间更少。

    显然,如果您需要以“原子”方式进行所有更改,以便表的其他用户不会注意到部分完成的更新,则您不能这样做。

© www.soinside.com 2019 - 2024. All rights reserved.