Automated batch update or delete operation in SQL Server

If we perform update or delete operation on huge number of rows in a large table at once, there are chances that the SQL Server would freeze or would cause outage. And if we try to kill the transaction in the middle, we might end up in a more dangerous “rollback” state. That’s why I spent some time to build this script that helps in automated batch operation in small chunks with constant check for query performance. The script would increase the chunk size based on the time taken by the each execution so that it would end at maximum achievable chunk size that has adequate performance.

declare @starttime datetime, @endtime datetime, @duration int,
		@status bit, @chunksize int,
		@bearableDuration int, @unbearableDuration int,
		@rowcount int

set @status = 0
set @chunksize = 100
set @bearableDuration = 100	--(ms) This value helps increase the batch/chunk size based on performance
set @unbearableDuration = 1000	--(ms) This value helps quit the transaction when there is too much delay.
				-- In this example, the program will exit when a chunk takes more than 100 ms to execute

	-- ============= Provide query to fetch the rowcount for the data to be manipulated (Modify here as needed) =
			select @rowcount = count(id)
			from detail where address  <> 'pppppppppppppppppppppppppppppppp'
								-- Rowcount for the entire batch operation
	-- ############# Rowcount query ends here ###########################################

while(@status = 0)
begin
	set @starttime=getdate()
	begin transaction
	-- ============= THE UPDATE/DELETE STATEMENT (Modify here as needed) ===============
	
		update top(@chunksize) dbo.detail
		set address = 'pppppppppppppppppppppppppppppppp'
		where address  <> 'pppppppppppppppppppppppppppppppp'

	-- ############# THE UPDATE/DELETE STATEMENT ENDS HERE ##############################
	commit transaction
	set @endtime=getdate()
	set @rowcount = @rowcount - @chunksize

	set @duration = datediff(ms, @starttime, @endtime)

	if(@duration < @bearableDuration)
	begin
		set @chunksize = @chunksize + 100
		print 'Duration: '+convert(varchar, @duration)+'. Increasing chunksize to ' + convert(varchar, @chunksize)
	end
	
	if (@duration > @unbearableDuration)
	begin
		set @status = 1
		print 'Exiting due to unbearable duration ' + convert(varchar,@duration) + ' at chunk size ' + convert(varchar, @chunksize)
	end
	
	if(@rowcount<=0)
	begin
		set @status = 1
		print 'Bulk operation has completed succesfully'
	end
end

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.