TRUNCATE TABLE の使用による全行削除

TRUNCATE TABLE ステートメントを使用すると、迅速かつ効率的にテーブルのすべての行を削除できます。TRUNCATE TABLE は、WHERE 句を使用しない DELETE ステートメントに似ています。ただし、TRUNCATE TABLE の方が高速で、システムおよびトランザクション ログのリソースも DELETE ほど使用されません。

DELETE ステートメントと比較した場合、TRUNCATE TABLE には次の利点があります。

  • 使用されるトランザクション ログの領域が DELETE よりも少ない。

    DELETE ステートメントでは、一度に 1 行ずつ削除し、削除した各行のエントリをトランザクション ログに記録します。TRUNCATE TABLE では、テーブルのデータを格納するために使用したデータ ページの割り当てを解除することによってデータを削除します。さらに、ページの割り当ての解除だけをトランザクション ログに記録します。

  • 通常使用されるロックが DELETE よりも少ない。

    DELETE ステートメントが行ロックを使用して実行されると、削除のためにテーブル内の各行がロックされます。TRUNCATE TABLE では常にテーブルとページがロックされますが、各行はロックされません。

  • 例外が発生することなく空のページがテーブル内に残される。

    DELETE ステートメントの実行後も、テーブルで空のページを保持できます。たとえば、ヒープ内の空ページの割り当てを解除するには、少なくとも 1 つの排他テーブル ロック (LCK_M_X) が必要です。削除操作でテーブル ロックを使用しない場合、そのテーブル (ヒープ) には空のページが多数含まれることになります。インデックスの場合は、削除操作で空のページが残ることがありますが、これらのページはバックグラウンドのクリーンアップ プロセスによってすぐに割り当てが解除されます。

TRUNCATE TABLE で空になったテーブルの定義は、DELETE の場合と同様に、そのインデックスや他の関連するオブジェクトと共にデータベースの中に残ります。テーブルに ID 列が含まれている場合は、その列に対するカウンタは、その列に対して定義されたシード値にリセットされます。シードが定義されていない場合は、既定値の 1 が使用されます。ID カウンタを保持するには、代わりに DELETE を使用します。

大きなテーブルの切り捨て

Microsoft SQL Server では、削除に必要なすべてのエクステントに対する同時ロックを保持することなく、128 を超えるエクステントを持つテーブルの削除または切り捨てを行う機能が導入されました。詳細については、「ラージ オブジェクトの削除と再構築」を参照してください。

次の例では、JobCandidate テーブルからすべてのデータを削除しています。SELECT ステートメントを TRUNCATE TABLE ステートメントの前後に挿入して結果を比較しています。

    USE AdventureWorks2008R2;
    GO
    SELECT COUNT(*) AS BeforeTruncateCount 
    FROM HumanResources.JobCandidate;
    GO
    TRUNCATE TABLE HumanResources.JobCandidate;
    GO
    SELECT COUNT(*) AS AfterTruncateCount 
    FROM HumanResources.JobCandidate;
    GO