SQL Server - READPAST, UPDLOCK update method?

Kah*_*ahn 5 sql sql-server locking sql-server-2012

We're in need of yet another massive update which as it is, would require downtime because of the risk of extensive locking problems. Basically, we'd like to update hundreds of millions of rows during business hours.

Now, reducing the updates to manageable < 5000 batch sizes helps, but I was wondering if it was feasible to create a template to only read and lock available rows, udpate them, and move on to the next batch? The idea is that this way we could patch some 95% of the data with minimal risk, after which the remaining set of data would be small enough to just update at once during a slower period while watching out for locks.

Yes, I know this sounds weird, but bear with me. How would one go about doing this?

I was thinking of something like this:

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
Run Code Online (Sandbox Code Playgroud)

Any ideas? Basically, the last thing I want is for this query to get stuck in other potentially long-running transactions, or to do the same to others in return. So what I'm looking for here is a script that will skip locked rows, update what it can with minimal risk for getting involved in locks or deadlocks, so it can be safely run for the hour or so during uptime.

Ros*_*ury 4

只需将WITH(READPAST)添加到表中即可进行单表更新:

UPDATE TOP (5000) MYTABLE WITH (READPAST)
SET VALUE = 'ASD'
WHERE X = Y AND Z = W etc...
Run Code Online (Sandbox Code Playgroud)

如果您足够幸运,只涉及一个表,您只需添加WITH(READPAST),UPDATE 本身将仅在更新的行上添加排他锁。

如果涉及多个表,则可能会变得更加复杂。还要非常小心 WHERE 子句,因为这可能会增加比预期更多的负载 - 前几批还不错,但如果需要扫描整个表才能找到足够的行来满足 TOP,则情况会变得越来越糟。您可能需要考虑每个批次的较短超时值。