2012-03-23 8 views
1

ディスク容量が不足しているため、約600万行のテーブルから約500万行を削除する必要があります。それらを削除する簡単な方法はありますか?バッチでdeleteを呼び出そうとしましたが、実行には非常に時間がかかり、時にはロックのためにエラーがスローされ、何もしません。ディスク容量が不足しているときにテーブルから複数の行を削除する

編集:

私は

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

のようなものが小さいバッチを取得するには、今の問合せをしていた、クエリは、私がなっていた以下の

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

エラーがありましたそれはテーブルにロックを取得できませんでした。私は現時点では正確なテキストを持っていないが、私は再びそれに実行する場合、私は行を削除する唯一の方法は、DELETE FROM <table> WHERE <some condition>のいずれかにある、ここで

答えて

2

を貼り付け、またはTRUNCATE TABLE <table>またはDROP TABLE <table>のいずれかですべての行を削除します(そしてそれを再作成する)。

これ以上の具体的な答えが得られる情報はありませんでしたが、恐れ入ります。 WHERE節の条件を使用すると、小さな行セット(バッチ)で実行できます。 (「エラーをスローする」は、「エラーをスローする」ことは意味がありません。なぜなら、「エラー」とは何の情報も無ければ役に立たないからです)。

+0

曖昧さのため申し訳ありませんが、上記の質問を編集しました。 – Carlos

1

あなたの状況に私の提案はありますか?レコードを削除すると、削除するすべてのレコードがログに記録され、余分なディスク容量が必要になるため、テーブルを切り捨てて、テーブルを切り捨てます。テーブルを切り捨てた後、ソリッド "temp"テーブルのレコードを元のテーブルに追加し、ソリッド "temp"テーブルをドロップします。

あなたができることは、データベース上でCHECKPOINTを実行して縮小することです。ディスク上のスペースを解放する必要があります。

0

前の2つの回答は絶対に間違いありません。

あなたが探しているものを使用すると、(a)のテーブルを参照する外部キーを持っている、または(b)のID列を持っている場合

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

次これは、もう少し複雑になります。前者の場合、外部キー制約を使用してテーブル内のレコードを参照するすべてのレコードを削除し、制約を削除してから、外部キーを切り捨てて再作成する必要があります。後者の場合、あなたは、INSERTステートメントの次を使用することができます。

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

をここでログが1年より古いログテーブルを削除するためのコードは、です。バッチループで。

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 
関連する問題