DELETE
コマンドとTRUNCATE
コマンドの違いについて理解を深めようとしています。内部についての私の理解は、次のようなものです。
DELETE
->データベースエンジンは、関連するデータページおよび行が入力されているすべてのインデックスページから行を見つけて削除します。したがって、インデックスが多いほど、削除に時間がかかります。
TRUNCATE
->テーブルのすべてのデータページをまとめて削除するだけで、テーブルの内容を削除するためのより効率的なオプションになります。
上記が正しいと仮定します(正しくない場合は修正してください)。
DELETE->データベースエンジンは、関連するデータページと、その行が入力されているすべてのインデックスページから行を見つけて削除します。したがって、インデックスが多いほど、削除に時間がかかります。
はい、ここには2つのオプションがあります。ベーステーブルの削除を実行するのと同じ演算子によって、非クラスター化インデックスから行ごとに行を削除できます。これは、狭い(または行ごとの)更新計画と呼ばれます。
または、非クラスター化インデックスの削除は、非クラスター化インデックスごとに1つずつ、別々のオペレーターによって実行される場合があります。この場合(ワイド、またはインデックスごとの更新プランと呼ばれます)、一連のアクションはすべて、インデックスごとに1回再生される前に作業テーブル(eagerスプール)に保存されます。多くの場合、特定の非クラスター化インデックスのキーによって明示的に並べ替えられ、順次アクセスパターン。
TRUNCATE->は、テーブルのすべてのデータページをまとめて削除するだけで、テーブルのコンテンツを削除するためのより効率的なオプションになります。
はい。 TRUNCATE TABLE
は、いくつかの理由でより効率的です。
異なる回復モードは各ステートメントにどのように影響しますか?何か効果はありますか?
削除は常に完全にログに記録されます(削除されたすべての行はトランザクションログに記録されます)。復旧モデルがFULL
以外の場合、ログレコードの内容には若干の違いがありますが、これは技術的に完全なロギングです。
削除するとき、すべてのインデックスがスキャンされますか、それとも行があるインデックスのみですか?すべてのインデックスがスキャンされている(シークされていない)と思いますか?
インデックス内の行の削除(前に示したナローまたはワイドの更新プランのいずれかを使用)は、常にキーによるアクセス(シーク)です。削除された各行のインデックス全体をスキャンすることは、恐ろしく非効率的です。前に示したインデックスごとの更新プランをもう一度見てみましょう。
実行プランは需要主導型のパイプラインです。親オペレーター(左側)は、子オペレーターに一度に行を要求することで、子オペレーターに作業を実行させます。ソート演算子はブロックしています(最初のソートされた行を生成する前に入力全体を消費する必要があります)が、その最初の行を要求する親(インデックス削除)によって引き続き駆動されています。インデックスの削除は、完了したソートから一度に行をプルし、各行のターゲット非クラスター化インデックスを更新します。
幅広い更新プランでは、基本テーブルの更新演算子によって列が行ストリームに追加されることがよくあります。この場合、クラスター化インデックスの削除により、非クラスター化インデックスのキー列がストリームに追加されます。このデータは、ストレージエンジンが非クラスター化インデックスから削除する行を見つけるために必要です。
コマンドはどのように複製されますか? SQLコマンドは各サブスクライバーで送信および処理されますか?または、SQL Serverはそれよりも少しインテリジェントですか?
トランケーションは、トランザクションレプリケーションまたはマージレプリケーションを使用してパブリッシュされたテーブルでは 許可されません です。削除が複製される方法は、複製のタイプとその構成方法によって異なります。たとえば、スナップショットレプリケーションは、一括方式を使用してテーブルの特定の時点のビューを複製するだけです。増分変更は追跡または適用されません。トランザクションレプリケーションは、ログレコードを読み取り、サブスクライバーで変更を適用するための適切なトランザクションを生成することによって機能します。マージレプリケーションは、トリガーとメタデータテーブルを使用して変更を追跡します。
関連資料: データを変更するT-SQLクエリの最適化