削除と切り捨て


35

コマンドDELETETRUNCATEコマンドの違いをより深く理解しようとしています。内部についての私の理解は、次のようなものに沿っています。

DELETE->データベースエンジンは、関連するデータページおよび行が入力されているすべてのインデックスページから行を見つけて削除します。したがって、インデックスが多いほど、削除に時間がかかります。

TRUNCATE ->すべてのテーブルのデータページをまとめて削除するだけで、テーブルの内容を削除するためのより効率的なオプションになります。

上記が正しいと仮定します(正しくない場合は修正してください):

  1. さまざまな回復モードが各ステートメントにどのように影響しますか?なんらかの効果がある場合
  2. 削除するとき、すべてのインデックスがスキャンされますか、それとも行があるインデックスのみがスキャンされますか?私はすべてのインデックスがスキャンされていると仮定します(シークされませんか?)
  3. コマンドはどのように複製されますか?SQLコマンドは各サブスクライバで送信および処理されますか?それとも、MSSQLはそれよりも少しインテリジェントですか?

2
上のいくつかの関連する情報があるDELETETRUNCATEの回答で、この質問のユーティリティのTRUNCATE直前に-ingがDROP。また、この回答で説明されている手法を使用して、両方のコマンドの効果を調べるためにログを自分で掘り下げることもできます
ニックチャマス

1
この回答は、DELETEおよびTRUNCATE操作の内部を示しています。また、質問は、TRUNCATEがより適切に機能する特定の状況を示しています。
孔夫子

5
@idstam TRUNCATEはロールバックできます。ニックは、彼がリンクした質問への答えでそれをカバーしてます。
マークストーリースミス

Truncateには、「alter table」権限が必要です(truncateは削除の代わりにプラグインであるという意味で)。
crokusek

回答:


58

DELETE->データベースエンジンは、関連するデータページおよび行が入力されているすべてのインデックスページから行を検索して削除します。したがって、インデックスが多いほど、削除に時間がかかります。

はい。ただし、ここには2つのオプションがあります。行は、ベーステーブルの削除を実行する同じ演算子によって、非クラスター化インデックスから行ごとに削除できます。これは、狭い(または行ごとの)更新計画として知られています。

行ごとの削除

または、非クラスター化インデックスの削除は、非クラスター化インデックスごとに1つずつ、別々の演算子で実行できます。この場合(ワイド、またはインデックスごとの更新プランと呼ばれます)、アクションの完全なセットは、インデックスごとに1回再生される前にワークテーブル(イーガースプール)に格納されます。アクセスパターン。

インデックスごとの削除

TRUNCATE->テーブルのすべてのデータページをまとめて削除するだけで、テーブルの内容を削除するためのより効率的なオプションになります。

はい。 TRUNCATE TABLEいくつかの理由でより効率的です:

  1. 必要なロックが少ない場合があります。通常、切り捨てに必要なのは、テーブルレベルでの単一のスキーマ変更ロック(および割り当て解除された各エクステントの排他ロック)だけです。削除は、より低い(行またはページ)粒度でロックを獲得し、割り当て解除されたページの排他ロックを獲得します。
  2. 切り捨てのみが、すべてのページがヒープテーブルから割り当て解除されることを保証します。排他テーブルロックヒントが指定されている場合でも(たとえば、データベースで行バージョン管理の分離レベルが有効になっている場合)、削除によってヒープに空のページが残る場合があります。
  3. 切り捨ては、使用中の復旧モデルに関係なく、常に最小限に記録されます。ページの割り当て解除操作のみがトランザクションログに記録されます。
  4. オブジェクトのサイズが128エクステント以上の場合、トランケーションは遅延ドロップを使用できます。遅延ドロップは、実際の割り当て解除作業がバックグラウンドサーバースレッドによって非同期に実行されることを意味します。

さまざまな回復モードが各ステートメントにどのように影響しますか?効果はありますか?

削除は常に完全にログに記録されます(削除されたすべての行はトランザクションログに記録されます)。復旧モデルが以外の場合、ログレコードの内容には若干の違いがありますFULLが、これはまだ技術的に完全なロギングです。

削除するとき、すべてのインデックスがスキャンされますか、それとも行があるインデックスのみがスキャンされますか?私はすべてのインデックスがスキャンされていると仮定します(シークされませんか?)

インデックス内の行の削除(前述のナローまたはワイドの更新プランを使用)は、常にキーによるアクセス(シーク)です。削除された各行のインデックス全体をスキャンするのはひどく非効率的です。前に示したインデックスごとの更新計画をもう一度見てみましょう。

ワイドプラン2

実行計画は需要主導型のパイプラインです。親演算子(左側)は、子演算子から一度に1行ずつ要求することで、子演算子を動作させます。ソート演算子はブロックしています(最初のソートされた行を生成する前に入力全体を消費する必要があります)が、それらはまだその最初の行を要求する親(インデックス削除)によって駆動されています。インデックスの削除、完了したソートから一度に1行ずつプルし、各行のターゲットの非クラスター化インデックスを更新します。

ワイド更新プランでは、ベーステーブル更新演算子によって列が行ストリームに追加されることがよくあります。この場合、クラスター化インデックスの削除により、非クラスター化インデックスキー列がストリームに追加されます。このデータは、ストレージエンジンが非クラスター化インデックスから削除する行を見つけるために必要です。

出力リストの詳細

コマンドはどのように複製されますか?SQLコマンドは各サブスクライバで送信および処理されますか?または、SQL Serverはそれよりも少しインテリジェントですか?

トランザクショナルレプリケーションまたはマージレプリケーションを使用して公開されたテーブルでは、切り捨ては許可さません。削除の複製方法は、複製のタイプとその構成方法によって異なります。たとえば、スナップショットレプリケーションは、一括方法を使用してテーブルのポイントインタイムビューをレプリケートするだけです。増分変更は追跡または適用されません。トランザクションレプリケーションは、ログレコードを読み取り、適切なトランザクションを生成して、サブスクライバーで変更を適用することにより機能します。マージレプリケーションは、トリガーとメタデータテーブルを使用して変更を追跡します。

関連資料データを変更するT-SQLクエリの最適化

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.