SQL 更新语句必须保留日志文件中的所有行,以便它可以在失败时回滚。正如这个家伙所解释的,处理数百万行的最佳方法是忘记原子性并将更新批处理成 50,000 行(或其他):
--Declare variable for row count
Declare @rc int
Set @rc=50000
While @rc=50000
Begin
Begin Transaction
--Use Top (50000) to limit number of updates
--performed in each batch to 50K rows.
--Use tablockx and holdlock to obtain and hold
--an immediate exclusive table lock. This unusually
--speeds the update because only one lock is needed.
Update Top (50000) MyTable With (tablockx, holdlock)
Set UpdFlag = 0
From MyTable mt
Join ControlTable ct
On mt.KeyCol=ct.PK
--Add criteria to avoid updating rows that
--were updated in previous pass
Where m.UpdFlag <> 0
--Get number of rows updated
--Process will continue until less than 50000
Select @rc=@@rowcount
--Commit the transaction
Commit
End
这仍然存在一些问题,因为您需要知道您已经处理了哪些行,也许比这个人(和我!)更聪明的人可以用更多的 MSSQL 魔法来计算出更好的东西;但这应该是一个开始。