我负责一个OLAP数据库,在该数据库中,我发现进行一些清洗会带来一些好处。 我的第一个分析涉及5亿行,这些行将在大约50个表中删除。这通常占每个表的70%。
我遇到了一些解决方案,我需要使用一个tmp表,删除原始表,然后再次使用它……但是我有太多的依赖关系,我不想冒险走那条路
所以我去了另一个解决方案: 一点一点地删除,因此没有表锁。
这是我在堆栈溢出中找到的代码,我已尝试对其进行改进 删除4000 x 4000行。
set statistics time off
DECLARE @BATCHSIZE INT, @WAITFORVAL VARCHAR(8), @ITERATION INT, @TOTALROWS
INT, @MAXRUNTIME VARCHAR(8), @BSTOPATMAXTIME BIT, @MSG VARCHAR(500)
SET DEADLOCK_PRIORITY LOW;
SET @BATCHSIZE = 4000
SET @WAITFORVAL = '00:00:10'
SET @MAXRUNTIME = '18:00:00' -- 6 PM
SET @BSTOPATMAXTIME = 1 -- ENFORCE 6 PM STOP TIME
SET @ITERATION = 0 -- LEAVE THIS
SET @TOTALROWS = 0 -- LEAVE THIS
Begin TRY
WHILE @BATCHSIZE>0
BEGIN
-- IF @BSTOPATMAXTIME = 1, THEN WE'LL STOP THE WHOLE JOB AT A SET TIME...
IF (CONVERT(VARCHAR(8),GETDATE(),108) >= @MAXRUNTIME AND @BSTOPATMAXTIME=1) OR @ITERATION >2000
BEGIN
Return;
END
DELETE top (@BATCHSIZE)
FROM FacY where IdDimX not in (select IdDimX from vwX)
SET @BATCHSIZE=@@ROWCOUNT
SET @ITERATION=@ITERATION+1
SET @TOTALROWS=@TOTALROWS+@BATCHSIZE
SET @MSG = 'Iteration: ' + CAST(@ITERATION AS VARCHAR) + ' Total deletes:' + CAST(@TOTALROWS AS VARCHAR)
RAISERROR (@MSG, 0, 1) WITH NOWAIT
--COMMIT TRANSACTION;
END
end TRY
BEGIN CATCH
IF @@ERROR <> 0
AND @@TRANCOUNT > 0
BEGIN
PRINT 'There is an error occured. The database update failed.';
ROLLBACK TRANSACTION;
END;
END CATCH;
所以这花了大约30分钟到一个小时之间即可删除400万行。
相反,我现在尝试删除100000行,并在1分钟内删除,然后我尝试了100万行,并在5-6分钟内删除了。 然后我又去了1000万行,花了15分钟。 (但50GB的日志已满,占60%,所以我认为这是极限)
所以现在我想知道如果我最后删除大块的代码会更好吗?因为要花很多时间。
我不明白的是为什么用大块删除需要更少的时间?
感谢您的帮助
答案 0 :(得分:1)
本文希望可以帮助您理解为什么批量删除可以并且随着删除的发生而逐渐变慢,并且还包括更好的批量删除方法:
https://michaeljswart.com/2014/09/take-care-when-scripting-batches/