2012-03-23 152 views
1

我需要從具有大約600萬行的表中刪除大約500萬行,因爲我的磁盤空間不足。有沒有快速刪除它們的方法?我已經嘗試過在批處理中調用delete,但它需要很長時間才能運行,有時它會因爲鎖而引發錯誤,並且不會執行任何操作。當磁盤空間不足時從表中刪除多行

編輯:

我在做一個查詢這東西就像

delete from <table> where updated_timestamp < '2012-02-20' 

現在,爲了得到小批量,查詢是我得到以下

delete from <table> where id < [100000 row increments] 

錯誤是它未能鎖定桌子。我沒有此刻的確切內容,但如果我再碰到這個問題,我會在這裏

回答

2

粘貼,刪除行的唯一方法是要麼DELETE FROM <table> WHERE <some condition>,或一方TRUNCATE TABLE <table>DROP TABLE <table>刪除所有行(然後重新創建它)。

您提供的信息中沒有任何信息可以允許任何比這更具體的答案,恐怕。您可以使用WHERE子句中的條件在較小的行集(批次)中執行此操作。 (「有時拋出一個錯誤」對幫助你解決它沒有用,順便說一下,因爲「拋出一個錯誤」在沒有關於可能出現什麼「錯誤」的信息時是沒有意義的。)

+0

對不起,我編輯了上面的問題。 – Carlos 2012-03-23 03:06:55

1

我的建議在你的情況是選擇要保留在一個固定「臨時」表中的百萬條記錄,然後截斷表,因爲當您刪除記錄時,它會記錄您刪除到日誌中的所有記錄,這會佔用額外的磁盤空間。截斷表格後,將實體「臨時」表格中的記錄添加回原始表格,並放下實體「臨時」表格。

您可以做的其他事情是在數據庫上運行CHECKPOINT,然後縮小它。它應該釋放磁盤上的一些空間。

0

前面兩個答案是絕對正確的,你應該相信它。

什麼你要找的是以下

SELECT * INTO into #temp FROM <table> WHERE updated_timestamp >= '2012-02-20' 
TRUNCATE TABLE <table> 
INSERT INTO <table> SELECT * FROM #temp 

這變得更復雜些,如果你(一)有外鍵引用表,或(b)有標識列。對於前者,您需要通過外鍵約束刪除表中引用記錄的所有記錄,然後刪除約束,然後截斷並重新創建外鍵。對於後者,可以使用INSERT語句如下:

SET IDENTITY INSERT <table> ON 
INSERT INTO <table> (<field_list>) 
SELECT <field_list>) FROM #temp 
SET IDENTITY INSERT <table> ON 
0

這裏是刪除日誌表,其中log是超過一年的代碼。與批次循環。

declare @batch int 
declare @i int 
declare @j int 
set @batch = 1000 
set @j = (select (COUNT(*)/@batch) + 1 from LOG_TABLE 
       where ACCESS_DATE < dateadd(year,-1,getdate())) 
set @i = 0 
print @j 

while (@i < @j) 
BEGIN 



delete top (@batch) 
from LOG_TABLE 
where ACCESS_DATE < dateadd(year,-1,getdate()) 
SET @i = @i + 1 
END 
相關問題