Вместо подсчета количества строк, которые еще нужно удалить, вы должны либо использовать 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.