How to avoid UPDATE statement locking out the entire table when updating large number of records
Try to update in batches.
DECLARE @Batch INT = 1000
DECLARE @Rowcount INT = @Batch
WHILE @Rowcount > 0
BEGIN
;WITH CTE AS
(
SELECT TOP (@Batch) NewColumn,OldColumn
FROM SomeTable
WHERE NewColumn <> OldColumn
OR (NewColumn IS NULL AND OldColumn IS NOT NULL)
)
UPDATE cte
SET NewColumn = OldColumn;
SET @Rowcount = @@ROWCOUNT
END
I took @pacreely's approach (see his answer on this question) of updating in batches and created a update...top
variation. I added the (rowlock) hint tell SQL server to keep the locks at row level.
See update...top for details. Also note, that you cannot use order by
when using top
in update
, insert
, merge
, delete
statement so the referenced rows are not arranged in any order.
declare @BatchSize int = 1000
declare @RowCount int = @BatchSize
while @RowCount > 0
begin
update top (@BatchSize) SomeTable with (rowlock)
set NewColumn = OldColumn
where
NewColumn <> OldColumn or
(
NewColumn is null and
OldColumn is not null
)
select @RowCount = @@rowcount
end