我有一个包含 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 子句中的列是构成唯一索引的列)。
这听起来不对。我明白使用唯一索引会比使用主索引慢,但是这两个结果之间的性能仍然存在巨大差异!
有什么想法吗?
真的。
更新 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
) 以使两个更新“原子化”。