2010-01-04 104 views
0

我的問題是我需要從表中刪除大約60M記錄,而不會導致使用此表的其他進程造成死鎖。在這一點上,我幾乎完成了使用while循環來移除記錄,該循環每次只能處理大約1M個記錄,但它需要整天進行。SQL Server 2005高效刪除

Q1:從表中刪除大量數據,使表保持在線狀態並最小限度地影響其他需要在MS SQL Server 2005中使用此表的資源的最佳方式是什麼?

問題2:有沒有像Oracle中那樣在SQL Server中實現單個行鎖定(而不是表鎖定)的方法? (注意回答此問題可能會回答Q1)。

A2:就像@Remus Rusanu通知我,有一種方法可以用row level locking進行刪除。

回答

2

看到這個thread,原來的海報實際上做了一些測試併發布了最有效的方法。一個MVP原本是用一個選項來插入你想要保留的數據到臨時表中,然後截斷原始表並重新插入。

+0

我喜歡它。下一次,我必須做這樣的事情不得不給這個鏡頭。 – 2010-01-04 21:07:42

+0

我們最初計劃將記錄保留到新表中。然而測試表明,從頭開始重建索引的時間太長了。 – 2010-01-04 21:10:22

+0

我經常這樣做,它的作用就像一個魅力。比刪除大量的行要好得多。 – 2010-01-04 21:10:29

1

我最近剛剛做了類似的事情。我只是創建了一個SQL Server作業,每10分鐘刪除一百萬行。代碼如下

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
DELETE TOP 1000000 FROM BIG_TABLE WHERE CreatedDate <= '20080630' 

說的表格有大約900萬行開始。沒有注意到任何重大的性能問題。

+0

因此,我寫的腳本從很多表中刪除數據(其中大多數表中只有一條記錄),我是否需要在BEGIN TRAN之後聲明一次,還是必須在腳本中使用每條刪除語句? – 2010-01-04 21:15:14

+0

BEGIN TRANSACTION之前。 例如 SET TRANSACTION隔離級別READ UNCOMMITTED; 刪除表A 刪除表B COMMIT TRAN SET事務隔離級別YOUR_ORIGINAL_LEVEL – 2010-01-04 23:37:10

1

最有效的方法是使用分區切換,請參見Transferring Data Efficiently by Using Partition Switching。缺點是它需要提前規劃分區的部署方式。

如果分區切換不可用,那麼答案取決於實際的表模式。您最好發佈實際模式(包括所有索引,最重要的是集羣密鑰定義)以及符合刪除候選者的條件。

至於Q2,SQL Server自90年代中期以來就有行級鎖定,我不知道你實際要問什麼。

+0

如果妳downvote,解釋爲什麼 – 2010-01-04 21:21:39

+0

SQL Server有頁級鎖沒有行級鎖。 http://download.oracle.com/docs/cd/E12151_01/doc.150/e12156/ss_oracle_compared.htm – 2010-01-04 21:24:22

+2

我建議你堅持MSDN文檔的SQL Server功能,而不是Oracle的。有關SQL Server中可用的鎖定模式,請參閱http://msdn.microsoft.com/en-us/library/ms189849.aspx和http://msdn.microsoft.com/en-us/library/ms189286.aspx。即使您鏈接的Oracle營銷文檔中說'SQL 7.0具有行級鎖定',並且這指的是從1997年開始的SQL 7。當前版本爲10.5(2008 R2),並且行級鎖定已成爲SQL Server的默認操作數SQL 2000(即SQL 8.0)。基於這種過時的信息做出決定不可能導致很好的解決方案。 – 2010-01-04 21:32:56