Как можно уменьшить использование журнала транзакций при удалении из массивной таблицы в SQL Server? - PullRequest
2 голосов
/ 10 марта 2011

У меня была эта функция, которая удаляла исторические данные, которые больше не нужны, из большой таблицы с более чем 10 миллионами строк

DELETE FROM BigTable
WHERE DATEDIFF(month,dtmtimestamp, getdate()) > 2)

Затем я попробовал этот метод, чтобы уменьшить объем пространства, используемого журналом транзакций:

WHILE (SELECT COUNT(*) FROM BigTable WHERE DATEDIFF(month,dtmtimestamp, getdate()) > 2) > 0 BEGIN
    DELETE TOP 10000 FROM BigTable
    FROM BigTable
    WHERE DateDiff(month,dtmtimestamp, getdate()) > 2
CONTINUE END 

Это правильный метод?Или я собираюсь использовать больше журналов транзакций таким образом?

Какие-нибудь полезные советы для этого?

Приветствия,
Niko

Окончательный ответ:

DECLARE @Remainder INT
DECLARE @ChunkSize INT
SET @Remainder = (SELECT COUNT(id) FROM BigTable WHERE dtmtimestamp < DateAdd(month, -2, getdate()))
SET @ChunkSize = CEILING(@Remainder/100) /* Divide the total into 100 parts, whole integers only */
WHILE @Remainder BEGIN
    BEGIN TRANSACTION deletehistorical
    DELETE TOP (@ChunkSize)
    FROM BigTable
    WHERE dtmtimestamp < DateAdd(month, -2, getdate());
    SET @Remainder = @@ROWCOUNT;
    COMMIT TRANSACTION deletehistorical
END

Команда CHECKPOINT только сообщает механизму об удалении завершенных транзакций из журнала (в простом режиме восстановления), и, поскольку этот запрос фактически продолжает работать, каждый цикл транзакции все еще создается.Чтобы разбить транзакцию, я добавил BEGIN и COMMIT, чтобы база данных каждый раз принимала эти изменения.

Ответы [ 4 ]

4 голосов
/ 10 марта 2011

Вместо подсчета количества строк, которые еще нужно удалить, вы должны либо использовать EXISTS (поэтому, как только он находит строку, он возвращает):

WHILE EXISTS(SELECT * FROM BigTable WHERE DATEDIFF(month,dtmtimestamp, getdate()) > 2) BEGIN

Или подлый:

select top 1 * from sysobjects /* Force @@ROWCOUNT > 0 */
WHILE @@ROWCOUNT BEGIN
    DELETE TOP 10000 FROM BigTable
    FROM BigTable
    WHERE dtmtimestamp< DateAdd(month, -2,getdate())
CONTINUE END

Где единственными поисками в таблице являются те, которые используются для фактического удаления.

Я также перемещался по вашей логике даты, если столбец dtmtimestamp имеет полезный индекс.

Редактировать Конечно, как указывает Мартин, ни один из этих адресов не использует журнал транзакций.

Стратегия ограничения удалений является разумной, чтобы остановить ужасное использование журнала, но она также должна иметь много резервных копий или сокращений журнала, происходящих в одно и то же время, чтобы можно было повторно использовать старое пространство журнала транзакций. В противном случае он все равно будет расти в журнале.

Если вы знаете, что резервное копирование журналов происходит, скажем, каждые пятнадцать минут, вы можете приостановить цикл каждые "n" итераций с WAYITFOR DELAY, чтобы вы знали, что предыдущее использование журнала транзакций было скопировано / очищено. Что бы ни случилось, пока вы удаляете, а не усекаете, запись журнала для каждой удаленной строки все равно будет занимать место в журнале или резервной копии журнала.

Если вы можете перевести все, что обычно использует эту систему в автономный режим, и объем строк, которые вы хотите сохранить, значительно меньше, чем те, которые вы хотите удалить, вы можете скопировать строки, чтобы сохранить их в другой таблице, удалите все внешние ключи, обрежьте таблицу, скопируйте сохраненные строки обратно и восстановите внешние ключи. YMMV.

1 голос
/ 10 марта 2011

Поскольку ваша база данных находится в простом восстановлении, ваш скрипт должен выдавать команды

CHECKPOINT 1;

после каждой N-итераций для освобождения журнала.

1 голос
/ 10 марта 2011

измените режим восстановления на простой для базы данных, внесите обновления / удаления, затем вернитесь к предыдущему режиму восстановления.

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

В простой модели восстановления автоматическая контрольная точка ставится в очередь, если журнал заполнен на 70 процентов. Ограничение максимального размера файла журнала в свойствах базы данных предотвратит выход файла журнала за пределы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...