2017-07-05 9 views
1

テーブルから8000万以上の行を削除するより良い方法はありますか?テーブルから8000万以上の行を削除するより良い方法はありますか?

WHILE EXISTS (SELECT TOP 1 * FROM large_table) 
    BEGIN 
     WITH LT AS 
      (
       SELECT TOP 60000 * 
       FROM large_table 
      ) 
     DELETE FROM LT 
    END 

これが大きくなりすぎるから、私のトランザクションログを維持する仕事をしていませんが、私は、このプロセスはより速く行くようにする方法があるかどうかを知る必要がありますか?私は今、このスクリプトを実行している5日間以上のコンピュータを持っていましたが、私は非常に遠くない、非常に高速でした。

+5

は、あなただけの[ 'TRUNCATE'](https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql)を使用することができませんか?すべての行を削除していますか? – Rokuto

+0

Aaron Bertrandによってこの記事が見つかるかもしれません:[大規模な削除操作をチャンクに分割](https://sqlperformance.com/2013/03/io-subsystem/chunk-deletes) –

+1

5日以上?!?!あなたのテーブルにトリガーがありますか?これはあなたのトースターで実行されていますか? – Milney

答えて

0

テーブルを単にで切り捨てることができます。

TRUNCATE TABLE large_table 
GO 

whereを使用すると、deleteを使用することもできます。削除にかかる時間は、さまざまな側面に依存します。 WHILEループの条件でSELECTクエリを削除することで、コストを削減できます。

DECLARE @rows INT = 1 

WHILE (@rows>0) 
BEGIN 

    DELETE TOP 1000 * 
    FROM large_table 

    @rows = @@ROWCOUNT 

END 
+0

しかし、私のトランザクションログファイルは急速に増加しています。どうすればログプロセスを停止できますか? –

+0

上記のプロセスを実行しているジョブを一定の時間間隔で作成することができます。 –

+0

しかし、トランザクションログが大きすぎてプロセスが停止してしまいました。 –

-1

ログファイルがいっぱいになると、バルク削除によって大量のログが作成され、ロールバックが発生します。

バッチとして削除を実行して、すべてのトランザクションがコミットされていることを確認できます。

DECLARE @IDCollection TABLE (ID INT) 
DECLARE @Batch INT = 1000; 
DECLARE @ROWCOUNT INT; 

WHILE (1 = 1) 
BEGIN 
    BEGIN TRANSACTION; 

    INSERT INTO @IDCollection 
    SELECT TOP (@Batch) ID 
    FROM table 
    ORDER BY id 

    DELETE 
    FROM table 
    WHERE id IN (
      SELECT * 
      FROM @IDCollection 
      ) 

    SET @ROWCOUNT = @@ROWCOUNT 


    IF (@ROWCOUNT = 0) 
     BREAK 

    COMMIT TRANSACTION; 
END 
+0

テーブル変数は速度を上げません*。トランザクションはトランザクションログをクリーンアップしません*。各バッチの後でそれをクリーンアップする唯一の方法は、 –

+0

をバックアップすることです。[大きな削除操作をチャンクに分割する](https://sqlperformance.com/2013/03/io-subsystem/chunk-deletes)をチェックします。各繰り返しの後に 'CHECKPOINT'または' BACKUP LOG'を実行する必要があります。 –

+0

操作が完了するまで、データベースの復旧モデルを単純に設定してください。 – gopimanikandan

関連する問題