如何在 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 中加快一列中所有值的简单更新的主要内容,如果未能解决你的问题,请参考以下文章

如何识别所有行的至少一列中具有值的 ID?

Mysql-如果我同时在表的一列中插入多个值,值的插入顺序是不是可能会改变?

一列中相同值的R子集行取决于另一列中的多个值

SQL:如何为一列中具有重复值的每组行选择一行?

SQL选择一列中具有重复值的所有行

如何在R中的一列中添加具有不同值的新行