對SQL語句中要刪除的行數應該設置什麼限制?SQL DELETE - 最大行數
我們需要刪除1到幾十萬行,並且需要應用某種最佳實踐限制,以便在每次我們清空垃圾籃時不會絕對殺死SQL服務器或填寫日誌。
此問題不是特定於任何類型的數據庫。
對SQL語句中要刪除的行數應該設置什麼限制?SQL DELETE - 最大行數
我們需要刪除1到幾十萬行,並且需要應用某種最佳實踐限制,以便在每次我們清空垃圾籃時不會絕對殺死SQL服務器或填寫日誌。
此問題不是特定於任何類型的數據庫。
這是一個非常廣泛的問題,基本歸結爲「它取決於」。影響它的因素包括:
什麼是您的併發級別?刪除語句在受影響的行上放置排他鎖。取決於數據庫引擎,刪除的數據分佈等,可能會升級到頁面或整個表格。您的數據讀取器在刪除期間是否可以被阻止?
刪除語句有多複雜?你還加入了多少個其他表,還是有複雜的WHERE子句?有時,刪除行的標識可能比刪除本身更「昂貴」,因此一個大的刪除可能會「更便宜」。
你是否害怕死鎖?當你減小刪除的大小時,你的死鎖「腳印」就會減少。理想情況下,單行刪除將始終成功。
你關心吞吐量性能嗎?與任何SQL語句一樣,通常會有一定量的開銷(連接內容,查詢解析,返回結果等)。從單一連接的角度來看,1000行刪除將比1000 x 1行刪除更快。
不要忘記索引維護開銷,碎片清理或任何觸發器。它們也會影響你的系統。
總的來說,我的基準線每條語句有1000行。與我合作過的大多數系統(子企業)最終每刪除500到5000條記錄的甜點。我喜歡做這樣的事情:
set rowcount 500
select 1 -- Just to force @@rowcount > 0
while @@ROWCOUNT > 0
delete from [table]
[where ...]
+1,會補充說,如果你刪除了一定數量的行,有時候更好地處理它;所以刪除10然後100然後1000作爲數據庫緩存了一些工作,這kind'a你點4 – Ben 2011-12-29 22:33:24
你適合在一般有很多更多的支持代碼做什麼,但一個「虛擬」斜坡上升。我還發現,試圖達到「最大」行/秒刪除是相當無用的。更好的方法是找到一個可接受的窗口(比如15秒),並嘗試一次刪除多少行。在註釋僞代碼中:挑選100行以刪除。刪除並獲取時間信息。如果時間<15秒,則選擇ROWS * 1.5刪除;否則選擇行* 0.5刪除。重複。這將擴大您的基於時間的吞吐量,並且對數據庫上的其他活動很敏感。 – jklemmack 2012-01-03 20:33:20
對於未來的讀者,請參閱下面的@SQLPhil的答案。基於Microsoft Books Online,未來版本的SQL Server將不會授予'INSERT','UPDATE'或'DELETE'語句的'SET ROWCOUNT'。最好使用'TOP'語法。 – jklemmack 2016-12-06 15:48:16
一般的答案是刪除該表並重新創建它,這是一個性能良好的解決方案,而是適用於全表
如果有過程,函數,視圖等依賴於你要刪除表時會發生什麼?根本沒有任何理由,你會使他們無效。 – Ben 2011-12-29 22:30:59
除非你有很多觸發器或完整性約束的驗證,刪除不該手術費用不高。
但是,如果你關心性能,我最初的預感是將相應的行標記爲已刪除,然後在定期清理期間將其物理刪除。但是我並不是很喜歡這個,因爲你必須改變該表上的任何查詢來排除邏輯上的 - 但不是物理上刪除的行。
每當我看到經常刪除大量行的散裝數據庫,這讓我想起了數據模型或處理的設計是不是最佳的。爲什麼加載100萬行然後刪除它們?如果您需要執行諸如清除歷史數據之類的操作,請考慮表分區。
羅素。可能有一些原因可能會導致您載入一百萬條記錄;您可以在丟棄原始數據之前執行計算並存儲計算的值。但你確實有一個好點,適當的設計很重要。 – Leons 2011-12-31 17:41:36
雖然限制影響的行數您刪除使用SET ROWCOUNT選項,然後進行一個循環是非常好的(和我以前很多時候用它),要知道,從2012年起,SQL這不會是一個選項(見BOL)。
因此,另一個選擇可以是限制使用TOP子句被刪除的行數。即
SELECT 1
WHILE @@ROWCOUNT > 0
BEGIN
DELETE TOP (#)
FROM mytable
[WHERE ...]
END
這樣模糊的問題無法回答。沒有銀彈 – zerkms 2011-12-29 20:59:12
我們使用批量夜間移動作業將記錄從一個表格移動到另一個表格。我們運行的批量爲10,000,性能影響可以忽略不計。 – Dimitri 2011-12-29 21:01:51
您需要嘗試添加一些限制並監控服務器性能以獲得最佳答案。 – piotrekkr 2011-12-29 21:01:54