您認爲以下兩個語句中哪一個對於刪除大量行是最有效的?使用計數優化DELETE語句
聲明#1:
DELETE TOP (@count) FROM ProductInfo WHERE productId = @productid
聲明#2:派生表
DELETE t1 FROM (SELECT TOP (@count) * from ProductInfo
WHERE productId = @productId v) t1
您認爲以下兩個語句中哪一個對於刪除大量行是最有效的?使用計數優化DELETE語句
聲明#1:
DELETE TOP (@count) FROM ProductInfo WHERE productId = @productid
聲明#2:派生表
DELETE t1 FROM (SELECT TOP (@count) * from ProductInfo
WHERE productId = @productId v) t1
兩者既不。由於單個事務日誌增長問題,您在處理大量數據時需要批量刪除。假設你要刪除所有記錄,對於一個給定@ProductID:
declare @batchSize int = 10000;
do while(1=1)
begin
delete top(@batchSize) from ProductInfo where productId = @productId;
if (0 = @@rowcount)
break;
end
兩種形式刪除您發佈的基本一致,最重要的是該表是由基於productId
鍵集羣的關鍵組織。如果這不是真的,並且您有productId
的NC指數,則必須校準@batchSize以避免index tipping point。
由於這兩個查詢執行完全相同的任務,我會使用第一個,因爲它更簡單閱讀並理解。
(此外,由於這兩個查詢做同樣的工作,我懷疑他們會產生相同的執行計劃 - 你可以檢查這個?)
1.如果delete語句失敗會發生什麼?它是否在while循環中繼續? 2.如果刪除失敗,會發生什麼情況,它是否設置了rowcount = 0並且真正退出循環? – RPS 2010-09-28 17:17:13
向每個示例帖子添加錯誤處理將會膨脹該示例並稀釋該示例的值。但是,如果你明確要求錯誤處理,那麼我建議將它包裝在BEGIN TRY/BEGIN CATCH塊中。然後,根據錯誤是什麼進行適當的處理。 – 2010-09-28 17:31:11
一個@batchSize,除非它已通過各種方法明確禁用,否則它將導致鎖定升級。 – etliens 2010-09-28 17:58:30