SQL のTRUNCATE
との違いは何ですか?DELETE
回答がプラットフォーム固有のものである場合は、その旨を明記してください。
ベストアンサー1
相違点のリストを以下に示します。Oracle 固有の機能を強調表示しましたが、コミュニティの皆さんが他のベンダー固有の相違点も追加してくれることを期待しています。ほとんどのベンダーに共通する相違点は見出しのすぐ下に記述し、相違点を下に強調表示します。
総括
テーブルからすべての行をすばやく削除する必要があり、それを本当に実行したいと思っており、テーブルに対して外部キーがない場合は、TRUNCATE の方が DELETE よりも高速になる可能性があります。
以下に詳述するように、システム固有のさまざまな問題を考慮する必要があります。
ステートメントタイプ
削除はDML、切り捨てはDDL(DDL と DML とは何ですか?)
コミットとロールバック
ベンダーによって異なる
SQLサーバー
切り捨てはロールバックできます。
PostgreSQL
切り捨てはロールバックできます。
オラクル
TRUNCATE は DDL であるため、ステートメントの実行前と実行後の 2 つのコミットが関係します。したがって、TRUNCATE はロールバックできず、TRUNCATE プロセスで障害が発生すると、いずれにせよコミットが発行されます。
ただし、以下のフラッシュバックを参照してください。
宇宙の再生
削除ではスペースは回復しませんが、切り捨てではスペースが回復します
オラクル
REUSE STORAGE 句を使用すると、データ セグメントの割り当てが解除されないため、テーブルにデータを再ロードする場合に効率がわずかに向上します。最高水準点はリセットされます。
行スコープ
削除を使用すると、すべての行または行のサブセットのみを削除できます。切り捨てを使用すると、すべての行が削除されます。
オラクル
テーブルがパーティション化されている場合、個々のパーティションを個別に切り捨てることができるため、テーブルのすべてのデータを部分的に削除することが可能になります。
オブジェクトの種類
削除は、テーブルおよびクラスタ内のテーブルに適用できます。切り捨ては、テーブルまたはクラスタ全体にのみ適用されます。(Oracle 固有の可能性があります)
データオブジェクトID
オラクル
削除はデータ オブジェクト ID に影響しませんが、テーブルの作成以降に挿入が行われていない限り、切り捨てによって新しいデータ オブジェクト ID が割り当てられます。ロールバックされる単一の挿入でも、切り捨て時に新しいデータ オブジェクト ID が割り当てられます。
フラッシュバック(オラクル)
フラッシュバックは削除をまたいで機能しますが、切り捨てにより操作前の状態へのフラッシュバックが防止されます。
ただし、11gR2からは、Express Editionを除いてFLASHBACK ARCHIVE機能によりこれが可能になります。
Oracle での FLASHBACK の使用 http://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_flashback.htm#ADFNS638
特権
変数
オラクル
テーブルに対する削除権限は別のユーザーまたはロールに付与できますが、切り捨て権限は DROP ANY TABLE 権限を使用せずに付与することはできません。
やり直し/元に戻す
削除では、少量のやり直しと大量の元に戻す操作が生成されます。切り捨てでは、それぞれごくわずかな量が生成されます。
インデックス
オラクル
切り捨て操作により、使用できないインデックスが再び使用可能になります。削除では使用できなくなります。
外部キー
有効な外部キーがテーブルを参照している場合、切り捨ては適用できません。削除による処理は、外部キーの構成によって異なります。
テーブルロック
オラクル
切り捨てには排他テーブル ロックが必要で、削除には共有テーブル ロックが必要です。したがって、テーブル ロックを無効にすると、テーブルに対する切り捨て操作を防止できます。
トリガー
DML トリガーは切り捨て時には起動しません。
オラクル
DDL トリガーが利用可能です。
リモート実行
オラクル
Truncate はデータベース リンク経由では発行できません。
アイデンティティ列
SQLサーバー
切り捨ては IDENTITY 列タイプのシーケンスをリセットしますが、削除はリセットしません。
結果セット
ほとんどの実装では、DELETE
ステートメントは削除された行をクライアントに返すことができます。
たとえば、Oracle PL/SQL サブプログラムでは次のことが可能です。
DELETE FROM employees_temp
WHERE employee_id = 299
RETURNING first_name,
last_name
INTO emp_first_name,
emp_last_name;