В чем разница между этими 2 запросами удаления зацикливания в SQL Server - PullRequest
1 голос
/ 03 октября 2019

Я хочу найти разницу между выполнением запроса на удаление в цикле while с началом транзакции и без него. Я пытаюсь удалить 200 миллионов строк из 250 миллионов и продолжать что-то подобное в фоновом режиме. Я не могу усечь, потому что в таблице есть внешний ключ.

Это для SQL Server 2012. Я попробовал тот, у которого без слова начинаются транзакция и фиксация транзакции, и он работает нормально, но как только я помещаю слово начало транзакции и фиксацию внутри цикла while, таблица блокируется, а затемначинает откат, как только я прекращаю выполнение на SSMS. Лучше не использовать слово начать транзакцию? В чем разница.

SET NOCOUNT ON

DECLARE @Deleted_Rows INT;

SET @Deleted_Rows = 1;

WHILE @Deleted_Rows > 0

BEGIN

DELETE  TOP (4800) FROM s FROM mytable s
INNER JOIN Controltable f on s.fileid = f.fileid
where f.FileDate < GETDATE()-7

IF @@ROWCOUNT < @Deleted_Rows BREAK

    --WAITFOR DELAY '00:00:00:01';

END

против

SET NOCOUNT ON

DECLARE @Deleted_Rows INT;

SET @Deleted_Rows = 1;

WHILE @Deleted_Rows > 0

BEGIN
BEGIN TRANSACTION

DELETE  TOP (4800) FROM s FROM mytable s
INNER JOIN Controltable f on s.fileid = f.fileid
where f.FileDate < GETDATE()-7

IF @@ROWCOUNT < @Deleted_Rows BREAK

    --WAITFOR DELAY '00:00:00:01';
COMMIT TRANSACTION
END

Я подумал, что безопаснее использовать транзакцию начала и, поскольку она находится внутри цикла while, она будет фиксировать каждые 4800 строк и всякий раз, когдая останавливаю выполнение, это откатило бы только как 100 строк или кое-что, но вместо этого это откатило бы все миллионы строк. Когда я не использую транзакцию фиксации и транзакцию beging, она работает нормально и не выполняет откат. Просто удаляет 4800 строк и останавливается, как только я нажимаю «Остановить выполнение в SSMS». Что тут происходит? Я скучаю по полуколоннам? Это неправильный запрос? Есть ли лучший способ?

1 Ответ

0 голосов
/ 03 октября 2019

Ваша транзакция принятия после BREAK. Следовательно, при последнем запуске ваш цикл while прервется, и последний BEGIN TRANSACTION не будет иметь соответствующего COMMIT.

Следовательно, ваш скрипт выглядит так, как будто он всегда оставляет открытую транзакцию. Вам понадобится отдельный COMMIT после цикла while для последнего разорванного цикла.

...