MySQL 多更新可能的唯一键性能问题

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

我有一个包含 15 列的 MySQL 数据库表。它有2个索引;一个主要的 int(自动递增),以及一个跨 4 列的复合唯一索引,int、int、int 和 datetime。

该表当前有5.5M条目,使用以下方法导入SQL数据文件时,每个新的多INSERT(1.2M行)花费不到2分钟...

mysql -h localhost -P 3306 -u test_user -D my_database -C < data.sql

但是,当我尝试执行与上述类似的过程时,但使用多更新(仅 2,000 行!)使用单个语句并且仅更新 1 列,例如...

UPDATE table SET col15 = (CASE WHEN col2=x AND col3=y AND col4=z and col5=d THEN 'a' ... WHEN col2=x AND col3=y AND col4=z and col5=d THEN 'b' END);

...耗时 9 分钟(注意:WHEN 子句中的列是构成唯一索引的列)。

这听起来不对。我明白使用唯一索引会比使用主索引慢,但是这两个结果之间的性能仍然存在巨大差异!

有什么想法吗?

mysql performance unique
1个回答
0
投票

真的。

更新 2000 行需要:

  • 如果没有
    WHERE
    子句,将检查所有 5.5M 行。
  • 没有索引对
    CASE
    有用。
  • 保留每个修改行的副本——以防由于崩溃等原因需要回滚
  • 更新任何包含
    col5
    .
  • 的索引

9 分钟似乎很高,但您需要结合检查 550 万行并在其中的 2000 行上花费额外的时间。

假设你真的打算以同样的方式测试 col2/3/4,而不是 col5,我建议这会好得多:

UPDATE  table SET col15 = ( CASE 
          WHEN  col5=d THEN 'a' ... 
          WHEN  col5=e THEN 'b' END )
    WHERE  col2=x
      AND  col3=y
      AND  col4=z

一起

INDEX(col2, col3, col4)   -- in any order

重要的是要有一个过滤的

WHERE
。如果两个 WHEN 之间没有共同点,那么使用两个
UPDATEs
会更快。如果您需要它们“同时”发生,则将它们放入事务中 (
BEGIN...COMMIT
) 以使两个更新“原子化”。

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