假设我有一个包含两列 A 和 B 的表。在 A 列上有一个索引,但在 B 列上没有。 我想发出数百万个查询,例如:
UPDATE t1 SET b=b1 WHERE a=a1;
UPDATE t1 SET b=b2 WHERE a=a2;
....
a
的每个唯一值对应 1 到 100,000 行。平均约为 100。
对于每个更新语句,平均有 60% 的行不会更改,因为对于这些行,b
已经具有所需的值。对于 30% 的更新,不会更改任何匹配行。
使用这样的语句有意义吗?
UPDATE t1 SET b=b1 WHERE a=a1 AND b<>b1;
它会通过消除不必要的回写磁盘来加速这个过程,还是 Mysql 5 足够智能以识别没有任何更改并且不需要回写到磁盘?
最佳答案
无论哪种情况,MySQL 都必须读取行内容(无论是在磁盘上还是在缓存/缓冲池中)。在任何一种情况下,MySQL 都会在 a
上使用您的索引。作为起点。在任何一种情况下,如果 MySQL 已经具有 b
的目标值,则不会更新该行。 .因此,我看不到 MySQL 有任何方式可以从 b<>b1
中获益。条款。
可以说,根据工作负载和数据集,如果您更改 b<>b1
上的索引,查询(其中包含 a
)可能会受益成为 a
上的复合索引和 b
(以该顺序)。在这种情况下,它不必访问磁盘(或检查缓存/缓冲池)来查找哪些行特别需要更新(即您将利用您提到的 30% 和 60% ).话虽如此,现在您的索引将需要对 b
上的每个更新进行更新。 ,因此是成本,尽管我怀疑这种权衡可能是值得的。
关于MySql更新优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4686152/