web-dev-qa-db-ja.com

削除vs切り捨て

DELETEコマンドとTRUNCATEコマンドの違いについて理解を深めようとしています。内部についての私の理解は、次のようなものです。

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

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

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

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

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

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

Per row deletion

または、非クラスター化インデックスの削除は、非クラスター化インデックスごとに1つずつ、別々のオペレーターによって実行される場合があります。この場合(ワイド、またはインデックスごとの更新プランと呼ばれます)、一連のアクションはすべて、インデックスごとに1回再生される前に作業テーブル(eagerスプール)に保存されます。多くの場合、特定の非クラスター化インデックスのキーによって明示的に並べ替えられ、順次アクセスパターン。

Per index deletion

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

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

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

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

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

削除するとき、すべてのインデックスがスキャンされますか、それとも行があるインデックスのみですか?すべてのインデックスがスキャンされている(シークされていない)と思いますか?

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

Wide plan 2

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

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

Output list detail

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

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

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

59
Paul White 9