如何在 MySQL 中加快一列中所有值的简单更新
Posted
技术标签:
【中文标题】如何在 MySQL 中加快一列中所有值的简单更新【英文标题】:How to speed up a simple UPDATE of all values in one column, in MySQL 【发布时间】:2021-10-27 14:39:02 【问题描述】:在拥有超过 460 万条记录的表上,这需要花费数小时。
有没有办法加快速度?
UPDATE tableA
SET SKU = CONCAT("X-", tableA.supplier_SKU);
任何列上还没有索引。
EXPLAIN 表示行 = 460 万,过滤 = 100% !
【问题讨论】:
如果这是真正的更新查询,我会质疑这样做的必要性。至少为某些列添加一个公共前缀看起来很奇怪。 【参考方案1】:如果 SKU 上有一个(索引)索引,删除它、更新和重新创建可能会有所帮助。
你能先锁定表吗(确保没有其他用户阻止你的操作)?
lock tables tableA write;
?
你能创建另一个表,在那里更新然后重命名吗?
https://dev.mysql.com/doc/refman/5.7/en/rename-table.html
*note - 上面的链接描述了如何在一个语句中交换两个表。
460 万条记录听起来并不像应该花费数小时,除非您无法锁定表,因为其他用户不断更新它。
【讨论】:
我目前在任何列上都没有任何索引。 没有其他人在使用数据库。我只是用锁表尝试过。它仍然需要很长时间。 EXPLAIN 表示每次更新都会影响 %100 条记录。除非我理解错误,否则这似乎不对。我只需要读取一列并在同一行更新另一列。 我刚刚运行了带有 LOCK TABLES 和 UNLOACK TABLES 的语句,它的运行速度比以前快了很多。谢谢。 @Seeker 即使只有一两列受到影响,也必须读写整个磁盘块。这就是可能导致运行时间过长的原因。【参考方案2】:请提供SHOW CREATE TABLE tableA
。
缓慢的部分是在“提交”之前需要保存 460 万个“旧”行。
永远不要在 InnoDB 中使用 LOCK TABLES
。
您可以将任务分成块,以减少对其他操作的阻碍。 (但总时间可能会更长。)请参阅“分块”:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks
【讨论】:
以上是关于如何在 MySQL 中加快一列中所有值的简单更新的主要内容,如果未能解决你的问题,请参考以下文章