我们需要另一次大规模更新,因为存在大量锁定问题的风险,因此需要停机。基本上,我们希望在工作时间更新数亿行。
现在,将更新减少到可管理的< 5000个批量大小有帮助,但我想知道创建模板是否可行只读取和锁定可用行,更新它们,然后继续下一批?我们的想法是,通过这种方式,我们可以以最小的风险修补95%的数据,之后剩余的数据集足够小,可以在较慢的时间段内同时更新,同时注意锁定。
是的,我知道这听起来很奇怪,但请耐心等待。怎么会这样做?
我在考虑这样的事情:
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (5000) T
SET T.VALUE = 'ASD'
FROM MYTABLE T
JOIN (SELECT TOP 5000 S.ID
FROM MYTABLE S WITH (READPAST, UPDLOCK)
WHERE X = Y AND Z = W etc...) SRC
ON SRC.ID = T.ID
END
有什么想法吗?基本上,我想要的最后一件事就是让这个查询陷入其他可能长时间运行的事务中,或者对其他事务做同样的事情。所以我在这里寻找的是一个脚本,它将跳过锁定的行,更新它可以以最小的风险参与锁定或死锁,因此它可以在正常运行时间内安全运行一小时左右。
答案 0 :(得分:1)
只需将 WITH(READPAST)添加到表中即可获得单表更新:
UPDATE TOP (5000) MYTABLE WITH (READPAST)
SET VALUE = 'ASD'
WHERE X = Y AND Z = W etc...
如果你足够幸运,只涉及一个表,你可以添加WITH(READPAST),UPDATE本身将只对更新的行添加一个独占锁。
如果涉及多个表,则可能会变得更复杂。还要非常小心WHERE子句,因为这可能会增加比预期更多的负载 - 前几批很好但是如果需要扫描整个表来找到足够的行来满足TOP,则会逐渐变得更糟。您可能需要考虑每个批次的短暂超时值。