2010-09-28 4 views
2

Какое из следующих двух утверждений вы считаете наиболее эффективным для удаления большого количества строк?оптимизация оператора DELETE с подсчетом

Заявление # 1:

DELETE TOP (@count) FROM ProductInfo WHERE productId = @productid 

Заявление # 2: Производная таблица

DELETE t1 FROM (SELECT TOP (@count) * from ProductInfo 
       WHERE productId = @productId v) t1 

ответ

6

Оба и ни. Вам необходимо удалять пакеты при работе с большим количеством из-за проблем с ростом журнала транзакций. Предполагая, что вы хотите удалить все записи для данного @productId:

declare @batchSize int = 10000; 
do while(1=1) 
begin 
    delete top(@batchSize) from ProductInfo where productId = @productId; 
    if (0 = @@rowcount) 
     break; 
end 

Две формы УДАЛИТЬ вы вывесили в основном идентичен, главное, таблица организована кластерным ключом на основе productId ключа. Если это неверно и у вас есть индекс NC на productId, тогда значение @batchSize должно быть откалибровано, чтобы избежать index tipping point.

+0

1. Что произойдет, если инструкция удаления не удалась? Продолжается ли она в цикле while? 2. Что произойдет, если удаление не удалось, задает ли строка row = 0 и ложно выходит из цикла? – RPS

+0

Добавление обработки ошибок к каждому отдельному сообщению может раздувать образец и разбавлять значение примера. Но если вы явно запросите обработку ошибок, я бы рекомендовал обернуть их в блок BEGIN TRY/BEGIN CATCH. Затем вы обрабатываете ошибку соответствующим образом, исходя из того, что было ошибкой. –

+0

Размер файла @batchSize, который приведет к блокировке Escalation, если только он не был отключен с помощью различных методов. – etliens

2

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

(Кроме того, поскольку оба запроса выполняет ту же работу, как я подозреваю, что они порождают один и тот же план выполнения - вы можете проверить это?)

Смежные вопросы