UPDATE BETWEEN查询中将锁定哪些行?

时间:2017-11-09 21:46:20

标签: mysql sql-update locking innodb

我没有使用交易,我的存储引擎是InnoDB。我想用以下内容更新整个表:

UPDATE someTable set someColumn = CONCAT('somePrefix', SUBSTR(2, someColumn))

我被告知这样做会锁定整个表,直到查询完成大约200秒,这是不好的。

所以我想尝试迭代:

UPDATE someTable set someColumn = CONCAT('somePrefix', SUBSTR(2, someColumn)) WHERE id BETWEEN 1,50000

这会锁定前50,000行吗? id上有一个主键,这只需要4秒,这是一个更易于管理的锁定时间,但知道它是锁定整个表,只有50,000行,还是只有一个,这将是一件好事。在更新时一次排。

2 个答案:

答案 0 :(得分:1)

首先,您没有BETWEEN的正确语法。你想要:

... WHERE id BETWEEN 1 AND 50000

InnoDB将在UPDATE期间锁定所有已检查的行。如果使用索引列(主键符合索引),则只会锁定与条件匹配的行。

您可以在查询之前使用EXPLAIN来查看已检查行的数量,并查看rows列(请注意,这只是优化程序的粗略估计,而不是检查的行的精确计数)。 / p>

如果您处于REPEATABLE-READ事务中,它还将锁定该范围内的任何间隙。我猜这对你来说不是一个问题,但它会阻止任何人在这些空白中插入新行。如果需要避免这种情况,可以将事务隔离设置为READ-COMMITTED。

请务必及时提交您的交易(或使用自动提交)。 UPDATE完成后可以保持锁定,直到下一次COMMIT。

答案 1 :(得分:0)

它只是锁定所涉及的行。 (也就是说,50K。)

我会使用11构建一个用于分块的循环。我一次不会超过1K行。

以下是代码草图:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks