66

次の2つのステートメントを使用することの長所と短所の概要を教えてもらえますか。

TRUNCATE TABLE dbo.MyTable

vs

DELETE FROM dbo.MyTable

すべてが言われ、行われるとき、彼らは両方とも同じことをするようです。しかし、2つの間に違いがあるはずです。

4

11 に答える 11

93

TRUNCATEロールバックデータを生成しないため、非常に高速です。テーブルで使用されているデータページの割り当てを解除するだけです。

ただし、トランザクション中にこの削除を「元に戻す」機能が必要な場合はDELETE FROM、を使用する必要があります。これにより、ロールバックが可能になります。

編集: 上記はSQL Serverには正しくないことに注意してください(ただし、Oracleには適用されます)。SQL Serverでは、トランザクション内にいて、トランザクションがコミットされていない場合、切り捨て操作をロールバックすることができます。SQL Serverの観点から見ると、DELETE FROMとTRUNCATEの主な違いはのとおりです。「DELETEステートメントは一度に1行ずつ削除し、削除された各行のトランザクションログにエントリを記録します。TRUNCATETABLEは、データページの割り当てを解除してデータを削除します。テーブルデータを保存し、ページの割り当て解除のみをトランザクションログに記録するために使用されます。」

つまり、ページの割り当て解除のみがトランザクションログに記録されるため、TRUNCATE中のログは少なくなりますが、DELETE FROMを使用すると、各行の削除が記録されます。これが、TRUNCATEが非常に高速である理由の1つです。

また、MSDNリンクから、外部キー制約によって参照されているテーブル、インデックス付きビューに参加しているテーブル、またはトランザクションレプリケーションまたはマージレプリケーションを使用して公開されているテーブルを切り捨てることはできないことに注意してください。

編集2: もう1つの重要なポイントは、TRUNCATE TABLEがIDを最初のシードにリセットするのに対し、DELETEFROMは中断したところからインクリメントを続けることです。参照:ベンロビンソンの答え。

于 2010-07-15T14:02:27.493 に答える
48

他の回答で言及されていないもう1つの重要なポイントは、 IDを最初のシードTRUNCATE TABLEリセットする一方で、中断したところから増分を続けることです。DELETE FROM

于 2010-07-15T14:12:40.770 に答える
9

セキュリティの観点からのもう1つの違いは、TRUNCATEにはテーブルに対するALTER権限が必要であるのに対し、DELETEにはそのテーブルに対する(ドラムロール)DELETE権限が必要なだけであるということです。

于 2013-07-03T15:35:44.583 に答える
4

TRUNCATE TABLEトランザクションをログに記録しません。つまり、大きなテーブルでは非常に高速です。欠点は、操作を元に戻せないことです。

DELETE FROM削除される各行をトランザクションログに記録するため、操作に時間がかかり、トランザクションログが大幅に増加します。利点は、必要に応じて操作を元に戻すことができることです。

于 2010-07-15T14:07:48.410 に答える
3

SQLサーバーでの削除と切り捨ての概要

完全な記事については、この接続の後に取得してください:SQLServerでVsTruncateを削除します

ここに画像の説明を入力してください

/*Truncate - Syntax*/
TRUNCATE TABLE table_name

/*Delete - Syntax*/
DELETE FROM table_name
WHERE some_condition
于 2017-09-07T10:08:54.403 に答える
2

DeleteとTruncateは、操作が明示的なトランザクションで実行された場合にのみロールバックできると思います。それ以外の場合は、削除されたデータを回復するために復元を実行する必要があります

于 2013-04-24T15:44:33.493 に答える
1

基本的な違いは、ログに記録される方法にあります。DELETEとTRUNCATEのログは異なりますが、どちらもまったく同じ方法でロールバックできます。データを変更するすべての操作がログに記録されます。SQL Serverには、ログに記録されない操作などはありません。

于 2011-06-29T11:28:10.103 に答える
0

非常に重要で(imo)、他の回答で言及されていないことの1つは、行ロックを使用するのに対しTRUNCATE、スキーマ安定性ロックが必要なことです。以下を調べてみましょう。Sch-SDELETE

BEGIN TRANSACTION;

BEGIN TRY
    -- Truncate below will take LCK_M_SCH_S lock for TABLE_A
    TRUNCATE TABLE TABLE_A

    -- Lets say the query below takes 5 hours to execute
    INSERT INTO
        TABLE_A
    SELECT
        *
    FROM
        GIANT_TABLE (NOLOCK)
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
    THROW
END CATCH

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;

ここで、このクエリの開始から1〜2分後に、次のコマンドを実行しようとしたとします。

SELECT COUNT(*) FROM TABLE_A (NOLOCK)

NOLOCK句を使用したことに注意してください。今何が起こると思いますか?このクエリは5時間待機します。なんで?句はロックオンNOLOCKする必要がありますが、その句はすでにロックオンしているためです。まだトランザクションをコミットしていないため、その句の後でもロックはオンのままです。テーブルのロックとは、基本的に、列の追加/削除などによって変更されているか、切り捨てられていることを意味します。以下のようなものを実行することさえできません:Sch-STABLE_ATRUNCATESch-STRUNCATESch-STABLE_A

SELECT object_id('TABLE_A')

これも5時間スタックします。ただし、これをに置き換えるとTRUNCATE、テーブルにロックDELETE FROMがなくSch-S、上記のクエリがスタックしないことがわかります。

于 2017-05-26T07:28:30.463 に答える
0

DELETEvsのもう1つの違いTRUNCATEは、テーブルが破損した場合の動作です。

例えば:

DELETE FROM table_name;

エラーが発生します:

メッセージ3314、レベル21、状態3、行1

データベース'...'でログに記録された操作を元に戻すときに、ログレコードID()でエラーが発生しました。通常、特定の障害は、Windowsイベントログサービスのエラーとして以前にログに記録されます。バックアップからデータベースまたはファイルを復元するか、データベースを修復します。

メッセージ0、レベル20、状態0、行0

現在のコマンドで重大なエラーが発生しました。結果がある場合は、破棄する必要があります。

動作しTRUNCATEますが:

TRUNCATE TABLE table_name;
-- Command(s) completed successfully.
于 2017-08-10T16:50:11.073 に答える
0

さらに、すべての回答に加えて、考慮すべきもう1つのポイントは、テーブルのをTruncateトリガーしませんが、ステートメントは各行のテーブルのをトリガーします。delete triggerdeletedelete trigger

于 2018-08-11T10:43:21.010 に答える
-2

truncateはログを記録しませんが、deleteはログを実行します。そのため、大量のレコードがある場合、トランスログは膨大になります。

于 2010-07-15T14:02:43.950 に答える