0

假设我运行了这个语句:

UPDATE Employees set country='AU'

在 InnoDB 表上,Employees,大约有 1000 万行。

其他用户也通过如下 SQL 查询积极更新此表:

例如,一个用户,ID = 20,将他们的国家更改为 NZ:

UPDATE Employees set country='NZ' where id = 20
  1. 在这种情况下,在一般更新完成之前,是否会阻止对该表的任何进一步更新?
  2. 如果是这样,有没有办法允许特定更新和一般更新同时运行,如果它们没有更新同一行?(为了澄清我的意思:假设一般更新完成了对 ID 为 1 - 50 的员工的更新,现在正在更新员工 51 - ~ 1000 万,对于 ID 为 20 的员工的单一更新应该在不等待一般更新的情况下完成完成)
4

2 回答 2

0

让我们“跳出框框思考”...

有 2 列。一个与counter; 一 ( dy) 与DATE计数器的最后一个增量。然后使计数器的碰撞更复杂一些——即如果日期在今天之前,将其重置为 1。另外(总是)将日期更新为CURDATE().

就像是

UPDATE t
    SET counter = IF (dy = CURDATE(), counter + 1, 1),
        dy = CURDATE()
    WHERE id = 123

消除了大型的夜间更新。

要获取当天的计数器,

SELECT  IF (dy = CURDATE(), counter, 0) AS counter
    WHERE id = 123;

这种技术还避免了必须在午夜运行大更新。如果机器恰好在午夜停机(并且当天无法运行更新),则会出现二阶“错误”。

于 2020-11-15T06:48:42.903 回答
0
  1. 是的,第一次更新将对表中的所有记录设置排他锁,阻止其他查询对其进行更新。锁一直保持到事务提交为止。

  2. 不会。在事务运行时会持有锁,并在事务提交时释放。您可能希望以块的形式更新表,而不是一次大爆炸,避免第一次更新锁定整个表。或者,如果可能,在工作时间之外执行更新。

于 2020-11-14T13:50:13.527 回答