2011-02-07 12 views
0

テーブルがあり、削除する必要があるテーブルが約150万件あります。以前は、一時テーブルを使用していました。これにより、トランザクションログのサイズがかなり急速に増加しました。問題は、いったん1つの結果セットを実行すると、別の150万以上の結果がある場所に移動する必要があるということです。これのパフォーマンスはかなり遅く、テーブルをtempデータベースに書き込むのではなく、table変数を使用する必要があるのだろうかと思います。私は最初の150万件の+レコードを選択するとテンポラリテーブルとテーブル変数

EDIT私は一時テーブルを使用します。

答えて

2

テーブル変数とテンポラリテーブルの質問をサイドステッピングすることで、削除をバッチ処理してwhileループ内の小さなグループにする方がよいでしょう。これは、トランザクションログのサイズを妥当なものに保つための最善の策です。等

何か:

while (1=1) begin 
    delete top(1000) 
     from YourTable 
     where ... 

    if @@rowcount < 1000 break 
end /* while */ 
+0

残りのレコードをクリーンアップするために 'while'ループの最後に別の' delete'を持たなければならないと思いますか? –

+0

「トランザクション」ではどのように動作しますか?私は 'トランザクション'を 'while'の中に入れますか? –

+0

@アードマン:そうは思わない。 whileループは、削除によって固定されたバッチサイズ(私の例では1,000レコード)よりも小さいものが削除されると終了します。これは、必要な削除がすべて完了したことを示します。したがって、1,400行を削除すると、ループは2回実行され、最初に1,000レコード、次で400レコードが削除されます。 400 <1000がブレークをトリガします。 –

1

一般的に、私は使いやすいというだけの理由で、一時テーブルよりもテーブル変数を使用する方が好きです。私は一時テーブルの使用が正当であるケースはほとんどありません。ルーチンで一時テーブルをどのように使用しているかについては言及していませんが、2つのオプションをベンチマークすることをお勧めします。

+0

私は1.5mil +レコードを選択すると一時テーブルが使用されます。次に、tempテーブルを使用してレコードを削除します。 –

+0

@Ardman:行を直接削除するのではなく、一時表から削除する理由があります。どうして?あなたのロジックの概要を教えていただけますか? –

+0

申し訳ありませんが、私は一時テーブルから削除していません。私はレコードの私のリストを取得するために一時テーブルを使用します。次に、このリストを使用してテーブルからレコードを削除します。 –

0

テーブル変数は、少数のためのより適切であり、しばしばこのような大きな結果セットには適していません。テーブル変数のデータは、そのサイズのためにtempdbに書き込まれる可能性があります。 個人的には、大きな結果セットを扱うときに、テーブル変数が一時テーブルよりもずっと遅いことがわかりました。 SQL Server Centralのthis articleの最後に、それぞれのテーブルで100万行を使用する例では、一時テーブルを使用したクエリの完了に要した時間が6分の1以下でした。 個人的には、クエリの実際のテーブルにそれらを結合する必要がある場合、パフォーマンスに苦しむことが多いテーブル変数が見つかりました。

パフォーマンスが低下する場合は、少なくともデータベース自体の設定の一部である可能性があります。自動的に成長するように設定されていますか?それの回復モデルは何ですか?

+0

復旧モデルは 'FULL'です。おそらく 'SIMPLE'に変更し、' DELETE'を実行する方が速いでしょうか? –

+0

これは速くなりますが、既存のトランザクションログは消去されます。それがどの程度受け入れられるかは、ビジネス要件によって決まります。 DBのダウンタイムは許容されますか?その後、バックアップを行い、復旧モデルを変更し、削除を実行して、復旧モデルを元に戻すことができます。 – MartW

関連する問題