8

10000000レコードのテーブルがあるとします。この2つのソリューションの違いは何ですか?

  1. 次のようなデータを削除します:

    DELETE FROM MyTable
    
  2. アプリケーションを含むすべてのデータを行ごとに削除します。

    DELETE FROM MyTable WHERE ID = @SelectedID
    

最初のソリューションは最高のパフォーマンスを発揮しますか?ログとパフォーマンスにどのような影響がありますか?

4

7 に答える 7

22

削除する必要のある行に制限する必要があり、完全な削除を行わない場合、またはTRUNCATE TABLEを使用できない場合(たとえば、テーブルがFK制約によって参照されているか、インデックス付きビューに含まれている場合)、次のことができます。チャンクでの削除:

DECLARE @RowsDeleted INTEGER
SET @RowsDeleted = 1

WHILE (@RowsDeleted > 0)
    BEGIN
        -- delete 10,000 rows a time
        DELETE TOP (10000) FROM MyTable [WHERE .....] -- WHERE is optional
        SET @RowsDeleted = @@ROWCOUNT
    END

一般的に、TRUNCATEが最良の方法であり、可能であればそれを使用します。ただし、すべてのシナリオで使用できるわけではありません。また、TRUNCATEは、テーブルのIDENTITY値がある場合はそれをリセットすることに注意してください。

SQL 2000以前を使用している場合、TOP条件は使用できないため、代わりにSETROWCOUNTを使用できます。

DECLARE @RowsDeleted INTEGER
SET @RowsDeleted = 1
SET ROWCOUNT 10000 -- delete 10,000 rows a time

WHILE (@RowsDeleted > 0)
    BEGIN
        DELETE FROM MyTable [WHERE .....] -- WHERE is optional
        SET @RowsDeleted = @@ROWCOUNT
    END
于 2010-01-26T10:12:32.460 に答える
14

テーブルにその数のレコードがあり、それらをすべて削除する場合は、truncate <table>の代わりに検討する必要がありdelete from <table>ます。はるかに高速になりますが、トリガーをアクティブにできないことに注意してください。

詳細については、次を参照してください(この場合はSQL Server 2000):http: //msdn.microsoft.com/en-us/library/aa260621%28SQL.80%29.aspx

アプリケーション内のテーブルをごとに削除すると、dbmsは何も最適化できないため、すべてを削除することを事前に知らないため、長い時間がかかります。

于 2010-01-26T09:57:34.293 に答える
3

最初の方が明らかにパフォーマンスが優れています。

DELETE [MyTable]を指定すると、IDのチェックを行わずにすべてが消去されます。2つ目は、削除する前に毎回それぞれのレコードを見つけるために時間とディスク操作を浪費します。

また、テーブルの中央からレコードが消えるたびに、エンジンがディスク上のデータを凝縮したい場合があり、時間と作業が無駄になるため、さらに悪化します。

おそらく、クラスター化インデックス列に基づいて降順でデータを削除することをお勧めします。その後、テーブルは基本的にすべての削除操作で最後から切り捨てられます。

于 2010-01-26T09:53:33.913 に答える
3

オプション1は、非常に大きなトランザクションを作成し、ログ/パフォーマンスに大きな影響を与えるだけでなく、テーブルが使用できなくなるようにロックをエスカレートします。オプション2は遅くなりますが、ログへの影響は少なくなります(バルク/フルモードを想定)

すべてのデータを削除したい場合は、テーブルMyTableの切り捨ては両方よりも高速ですが、行をフィルタリングする機能はありませんが、後ろでメタデータの変更を行い、基本的にはテーブルのフロアにIAMをドロップします。質問。

于 2010-01-26T09:56:40.990 に答える
2

テーブルをクリアするための最高のパフォーマンスはをもたらすでしょうTRUNCATE TABLE MyTable。詳細な説明については、http://msdn.microsoft.com/en-us/library/ms177570.aspxを参照してください。

于 2010-01-26T09:57:24.293 に答える
1

この投稿はMicrosoftTechNetで見つかりました。

基本的に、次のことをお勧めします。

  1. SELECT INTOを使用して、保持するデータを中間テーブルにコピーします。
  2. ソーステーブルを切り捨てます。
  3. INSERT INTOを使用して、中間テーブルからソーステーブルにデータをコピーして戻します。

..

BEGIN TRANSACTION

SELECT  *
   INTO    dbo.bigtable_intermediate
   FROM    dbo.bigtable
   WHERE   Id % 2 = 0;

   TRUNCATE TABLE dbo.bigtable;  

   SET IDENTITY_INSERT dbo.bigTable ON;
   INSERT INTO dbo.bigtable WITH (TABLOCK) (Id, c1, c2, c3)
   SELECT Id, c1, c2, c3 FROM dbo.bigtable_intermediate ORDER BY Id;
   SET IDENTITY_INSERT dbo.bigtable OFF;
ROLLBACK TRANSACTION
于 2014-09-03T20:10:36.087 に答える
0

1つ目はテーブルからすべてのデータを削除し、2つ目は特定のキーからのデータのみを削除するよりもパフォーマンスが向上します。

ここで、テーブルからすべてのデータを削除する必要があり、ロールバックの使用に依存しない場合は、切り捨てテーブルの使用を検討してください。

于 2010-01-26T09:58:03.857 に答える