行を削除すると、非クラスター化インデックスがより多くのスペースを使用するのはなぜですか?


22

75億行と5つのインデックスを持つ大きなテーブルがあります。約1,000万行を削除すると、非クラスター化インデックスが格納されているページ数を増やすように見えることに気付きました。

私はdm_db_partition_statsページの違いを報告するためのクエリを書きました(後-前):

dm_db_partition_statsデルタ

インデックス1はクラスター化インデックス、インデックス2は主キーです。その他は非クラスター化され、一意ではありません。

これらの非クラスター化インデックスでページが増えているのはなぜですか?
数値は最悪でも同じままになると予想していました。
削除中にパフォーマンスカウンターがページ分割の増加を報告するのを見ます。

削除するとき、ゴーストレコードは別のページに移動する必要がありますか?これは「一意性」と関係がありますか?

私たちはRCSIの展開を進めていますが、現在、RCSIはオフになっています。

これは、可用性グループのプライマリノードです。私はスナップショットがセカンダリで何らかの形で使用されていることを知っています。それが関連していた場合、私は驚くでしょう。これを掘り下げて(dbccページの出力を調べて)詳細を調べる予定です。誰かが似たようなものを見たことを願っています。


ただ質問-成長したインデックスの1つでREORGANIZEを実行すると、どうなりますか?いくつのページが削除されますか?削除する前に再編成すると、どうなりますか?私は主に、内部メカニズムが新しいページ全体を割り当ててマージする方が簡単な場合があると考えていますが、空のページをクリーンアップしません。REORGANIZEは、比較的断片化されていないが大きなインデックスでも、かなりの量のページをドロップすることを知っています。
バージルの笑い

良い質問@LaughingVergil答えが得られたら、ここに戻って報告します。(ただし、しばらく時間がかかる場合があります)。
マイケルJスワート

私たちの場合、この増加は一時的な現象でした。忍耐力が十分にあると、ゴーストのクリーンアップは最終的に作業を完了し、インデックスのサイズが小さくなりました。
マイケルJスワート

回答:


28

私を非常に楽しませる可能性のあるシナリオ:

  • 行は、データベースで読み取りコミットスナップショット(RCSI)、スナップショット分離(SI)、または可用性グループ(AG)が有効になっていないときに最初に書き込まれました。
  • RCSIまたはSIが有効になっているか、データベースが可用性グループに追加されました
  • 削除中に、RCSI / SI / AG読み取りをサポートするために、削除された行に14バイトのタイムスタンプが追加されました

このサーバーはAGのプライマリであるため、セカンダリと同様に影響を受けます。バージョン情報はプライマリに追加されます-データページはプライマリとセカンダリの両方でまったく同じです。セカンダリはバージョンストアを利用して、AGによって行が更新されている間に読み取りを行いますが、セカンダリは独自のバージョンのタイムスタンプをページに書き込みません。プライマリの作業からバージョンを継承するだけです。

成長を実証するために、(RCSIが有効になっていない)Stack Overflowデータベースエクスポートを使用して、Postsテーブルに一連のインデックスを作成しました。sp_BlitzIndex @Mode = 2でインデックスサイズをチェックしました(コピーしてスプレッドシートに貼り付け、情報密度を最大化するために少しクリーンアップしました)。

前のsp_BlitzIndex

次に、約半分の行を削除しました。

BEGIN TRAN;
DELETE dbo.Posts WHERE Id % 2 = 0;
GO

面白いことに、削除が行われている間、データファイルもタイムスタンプに対応するために成長していました。SSMSディスク使用率レポートには、成長イベントが表示されます。ここでは、説明するための最上部のみを示します。

成長イベント

(削除はデータベースを成長させるデモが大好きです。)削除の実行中に、sp_BlitzIndexを再度実行しました。クラスター化インデックスの行数は少なくなりますが、そのサイズは既に約1.5GB増えています。AcceptedAnswerIdの非クラスター化インデックスは劇的に成長しました-それらはほとんどがnullである小さな値のインデックスなので、インデックスサイズはほぼ2倍になりました!

削除中のsp_BlitzIndex

削除が完了するのを待つ必要はないので、そこでデモを停止します。ポイント:RCSI、SI、またはAGが有効になる前に実装されたテーブルで大規模な削除を行うと、インデックス(クラスター化を含む)が実際に大きくなり、バージョンストアのタイムスタンプの追加に対応できるようになります。


3
これが説明です。14バージョンのバイトが欠落する可能性のある他の状況があることがわかります。私のテストでは、オフラインでインデックスを再構築すると、バージョンバイトなしで行が再構築されるようです。
マイケルJスワート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.