TRUNCATE TABLE (Transact-SQL)
適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric のウェアハウス
個々の行の削除をログに記録せず、テーブルまたはテーブルの指定したパーティションからすべての行を削除します。 TRUNCATE TABLE
は、WHERE
句のないDELETE
ステートメントに似ていますが、TRUNCATE TABLE
は高速であり、使用するシステム ログ リソースとトランザクション ログ リソースが少なくなります。
構文
SQL Server および Azure SQL データベース の構文
TRUNCATE TABLE
{ database_name.schema_name.table_name | schema_name.table_name | table_name }
[ WITH ( PARTITIONS ( { <partition_number_expression> | <range> }
[ , ...n ] ) ) ]
[ ; ]
<range> ::=
<partition_number_expression> TO <partition_number_expression>
Microsoft Fabric、Azure Synapse Analytics、Parallel Data Warehouse の構文。
TRUNCATE TABLE { database_name.schema_name.table_name | schema_name.table_name | table_name }
[ ; ]
引数
database_name
データベースの名前。
schema_name
テーブルが属しているスキーマの名前です。
table_name
切り捨てるテーブルの名前、またはすべての行が削除されるテーブルの名前。 table_name はリテラルで指定する必要があります。 table_nameOBJECT_ID()
関数または変数にすることはできません。
WITH ( PARTITIONS ( { <"partition_number_expression"> | <"range"> } [ , ...n ] ) )
適用対象: SQL Server 2016 (13.x) 以降のバージョン。
切り捨てるパーティション、またはすべての行を削除するパーティションを指定します。 テーブルがパーティション分割されていない場合、 WITH PARTITIONS
引数はエラーを生成します。 WITH PARTITIONS
句が指定されていない場合、テーブル全体が切り捨てられます。
<partition_number_expression>
は以下の方法で指定できます。
WITH (PARTITIONS (2))
などのようにパーティション番号を指定しますコンマで区切った複数の個別のパーティションのパーティション番号を提供します。たとえば次のとおりです:
WITH (PARTITIONS (1, 5))
範囲と個別のパーティションの両方を提供します。たとえば次のとおりです:
WITH (PARTITIONS (2, 4, 6 TO 8))
<range>
は、TO
という単語で区切られたパーティション番号として指定できます。次に例を示します。WITH (PARTITIONS (6 TO 8))
パーティション テーブルの切り捨てを行うには、テーブルとインデックスが連携している (同じパーティション関数でパーティション分割されている) 必要があります。
解説
DELETE
ステートメントと比較すると、TRUNCATE TABLE
には次の利点があります。
トランザクション ログが使用する領域が削減されます。
DELETE
ステートメントは、一度に 1 行ずつ行を削除し、削除された行ごとにトランザクション ログにエントリを記録します。TRUNCATE TABLE
は、テーブル データを格納するのに使用するデータ ページの割り当てを解除することによってデータを削除し、ページの割り当ての解除だけをトランザクション ログに記録します。通常、使用されるロックの数が削減されます。
DELETE
ステートメントが行ロックを使用して実行されると、テーブル内の各行が削除のためにロックされます。TRUNCATE TABLE
常にテーブル (スキーマ (SCH-M
) ロックを含む) とページがロックされますが、各行はロックされません。テーブル内にページは一切残されません。
DELETE
ステートメントが実行された後も、テーブルには空のページを含めることができます。 たとえば、ヒープ内の空のページは、少なくとも排他 (LCK_M_X
) テーブル ロックなしでは割り当てを解除できません。 削除操作がテーブル ロックを使用しない場合は、テーブル (ヒープ) には多数の空のページが含まれます。 インデックスの場合、削除操作では空のページが残ることがありますが、バックグラウンド クリーンアップ プロセスではこれらのページの割り当てが迅速に解除されます。
TRUNCATE TABLE
はテーブルからすべての行を削除しますが、テーブル構造とその列、制約、インデックスなどが残ります。 テーブルのデータとテーブル定義を削除する場合は、DROP TABLE
ステートメントを使用します。
テーブルに ID 列が含まれている場合は、その列に対するカウンターは、その列に対して定義されたシード値にリセットされます。 シードが定義されていない場合は、 1
既定値が使用されます。 ID カウンターを保持するには、代わりに DELETE
を使用します。
TRUNCATE TABLE
操作は、トランザクション内でロールバックできます。
制限事項
次のテーブルで TRUNCATE TABLE
を使用することはできません。
FOREIGN KEY
制約によって参照されます。 それ自体を参照する外部キーを持つテーブルは切り捨てることができます。インデックス付きビューで使用されているテーブル。
トランザクション レプリケーションとマージ レプリケーションを使用してパブリッシュされているテーブル。
システムのバージョン情報のテンポラル テーブル。
EDGE
制約によって参照されます。
これらの特性の 1 つ以上を持つテーブルの場合は、代わりに DELETE
ステートメントを使用してください。
TRUNCATE TABLE
では、個々の行の削除がログに記録されないため、トリガーをアクティブ化できません。 詳細については、「 CREATE TRIGGER (Transact-SQL)」をご覧ください。
Azure Synapse Analytics と Analytics Platform System (PDW) では:
TRUNCATE TABLE
は、EXPLAIN
ステートメント内では使用できません。TRUNCATE TABLE
はトランザクション内で実行できません。
大きなテーブルを切り捨てる
Microsoft SQL Server は、削除に必要なすべてのエクステントに対する同時ロックを保持することなく、128 を超えるエクステントを持つテーブルの削除または切り捨てを行う機能を備えています。
アクセス許可
table_name で必要な最小限の権限は ALTER
です。 TRUNCATE TABLE
アクセス許可は、既定ではテーブル所有者、sysadmin、固定サーバー ロールdb_owner
およびdb_ddladmin固定データベース ロールのメンバーに設定され、転送できません。 ただし、TRUNCATE TABLE
ステートメントをストアド プロシージャなどのモジュール内に組み込み、EXECUTE AS
句を使用してそのモジュールに適切な権限を与えることはできます。
例
A. テーブルを切り捨てる
次の例では、JobCandidate
テーブルからすべてのデータを削除しています。 SELECT
ステートメントを TRUNCATE TABLE
ステートメントの前後に挿入して結果を比較しています。
USE AdventureWorks2022;
GO
SELECT COUNT(*) AS BeforeTruncateCount
FROM HumanResources.JobCandidate;
GO
TRUNCATE TABLE HumanResources.JobCandidate;
GO
SELECT COUNT(*) AS AfterTruncateCount
FROM HumanResources.JobCandidate;
GO
B. テーブル パーティションを切り捨てる
適用対象: SQL Server 2016 (13.x) 以降のバージョン。
次の例では、パーティション分割されたテーブルの指定パーティションを切り捨てます。 WITH (PARTITIONS (2, 4, 6 TO 8))
構文によりパーティション番号、2、4、6、7、および 8 が切り捨てられます。
TRUNCATE TABLE PartitionTable1
WITH (PARTITIONS (2, 4, 6 TO 8));
GO
C: 切り捨て操作をロールバックする
次の例は、トランザクション内の TRUNCATE TABLE
操作をロールバックできることを示しています。
3 行のテスト テーブルを作成します。
USE [tempdb]; GO CREATE TABLE TruncateTest (ID INT IDENTITY (1, 1) NOT NULL); GO INSERT INTO TruncateTest DEFAULT VALUES; GO 3
切り捨てる前にデータを確認します。
SELECT * FROM TruncateTest; GO
トランザクション内のテーブルを切り捨て、行数を確認します。
BEGIN TRANSACTION; TRUNCATE TABLE TruncateTest; SELECT * FROM TruncateTest;
テーブルが空であることがわかります。
トランザクションをロールバックし、データを確認します。
ROLLBACK TRANSACTION; GO SELECT * FROM TruncateTest; GO
3 つの行がすべて表示されます。
テーブルをクリーンアップします。
DROP TABLE TruncateTest; GO