クラスタ化インデックスで再構築しますが、なぜデータサイズが縮小するのですか?


10

約15 GBのデータが含まれ、データサイズが5 GBに縮小されたテーブルのクラスター化インデックスで再構築を行った場合、これはどのように行われますか?どのような「データ」が削除されますか?

データサイズは、DBCC sp_spaceusedの "data"列を意味します

クラスタ化インデックスで再構築する前:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    39169656 KB 15857960 KB 22916496 KB 395200 KB

クラスタ化インデックスで再構築した後:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    29076736 KB 5867048 KB  22880144 KB 329544 KB

再構築のためのTSQL:

USE [DAX5TEST]
GO
ALTER INDEX [I_212RECID] ON [dbo].[LEDGERJOURNALTRANS] REBUILD PARTITION = ALL WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, ONLINE = ON, SORT_IN_TEMPDB = OFF, DATA_COMPRESSION = PAGE, FILLFACTOR = 85 )
GO

ファイルサイズからデータサイズを決定していますか?
JNK

データサイズ私はDBCCの「データ」欄の意味は、sp_spaceusedを
ダニエル・ビョーク

それがの「データ」列になりEXEC sp_spaceusedます。
RLF 2014

1
OPが彼の再構築スクリプトで有効になっているページ圧縮=を使用していることをすべての人が見逃しましたか?ダニエルは確認できますか?
シャンキー2014

1
@Shanky:このALTER INDEXステートメントは、コードによって生成されたように見えます(デフォルト設定に多数のオプションが含まれているため)。これは、インデックスの既存のオプションから構築されたものだと思います。しかし、そうです。これが実行される前にクラスター化インデックスで圧縮有効にされていなかった場合、データフットプリントのほとんどの削減を確実に説明できます。(もう一度:ダニエル、どちらかを確認してもらえますか?)
デビッドスピレット2014

回答:


16

テーブルにクラスター化インデックスがある場合、インデックステーブルデータです(それ以外の場合は、ヒープタイプのテーブルがあります)。クラスタ化インデックス(実際には任意のインデックスですが、非クラスタ化インデックスの「データ」としてカウントされない)を再構築すると、部分的に使用されているページがより完全な形式にマージされます。

データをインデックス(クラスター化またはその他)でインデックスに挿入すると、必要に応じてリーフページが作成され、ページの最後の部分ページが1つだけになります。インデックス順にデータを入力するとき、データが適切な場所に収まるようにページを分割する必要があります。最終的に、約半分のページが2ページになり、新しい行がその1ページに入ります。時間の経過とともにこれが頻繁に発生し、かなりの量の余分なスペースが消費されますが、将来の挿入によってある程度のギャップが埋められます。非リーフページでも同様の効果が見られますが、実際のデータページの方がはるかに重要です。

また、削除するとページが部分的になる場合があります。ページ内のすべての行を削除すると、「未使用」としてカウントされますが、1つ以上のデータ行が残っている場合でも、使用中としてカウントされます。1ページに10バイトを使用する行が1つしかない場合でも、そのページは、使用されているスペースの数で8192バイトとしてカウントされます。繰り返しになりますが、将来の挿入によってギャップが埋められる可能性があります。

可変長の行の場合、更新によって同じ効果が得られる場合もあります。行が小さくなると、ページにスペースが残り、後で再利用するのが難しくなる可能性があります。ほぼ完全なページの行が長くなると、ページ分割が強制される可能性があります。 。

SQL Serverは、インデックスの再構築順序などが明示的に指示されるまで、ページの使用方法を再調整してデータを正規化しようとする時間を費やしません。そのようなガベージコレクションの演習はパフォーマンスの悪夢になる可能性があります。

これはあなたが見ているものだと思いますが、データが絶対に必要とする量の〜2.7倍に十分なスペースが割り当てられていることは、特に悪いケースだと思います。インデックス内の重要なキーの1つ(おそらくUUID列)としてランダムなものがあることを意味している可能性があります。つまり、新しい行がインデックス順に追加されることはほとんどありません。また、最近かなりの数の削除が発生しました。

ページ分割の例

4つがページに収まる固定長の行をインデックス順に挿入します。

Start with one empty page: 
        [__|__|__|__]
Add the first item in index order:
        [00|__|__|__]
Add the next three
        [00|02|04|06]
Adding the next will result in a new page:
        [00|02|04|06] [08|__|__|__]
And so on...
        [00|02|04|06] [08|10|12|14] [16|18|__|__]

ここで、インデックス順以外の行を追加します(これが上記の偶数のみを使用した理由です):追加する11と、2番目のページが拡張され(固定サイズのため不可能)、11を超えるものをすべて1つ上に移動します(コストが高すぎる)大きなインデックス)または次のようにページを分割:

[00|02|04|06] [08|10|11|__] [12|14|__|__] [16|18|__|__]

ここから追加する13と、17現在は関連ページに余裕があるため、分割は行われません。

[00|02|04|06] [08|10|11|__] [12|13|14|__] [16|17|18|__]

03を追加すると、次のようになります。

[00|02|03|__] [04|06|__|__] [08|10|11|__] [12|13|14|__] [16|17|18|__]

ご覧のとおり、これらの挿入操作の後、現在5行のデータページが割り当てられており、合計20行に相当しますが、そこには14行しかありません(スペースの30%を「無駄にしています」)。

デフォルトのオプション(「FILL FACTOR」については以下を参照)で再構築すると、次のようになります。

[00|02|03|04] [06|08|10|11] [12|13|14|16] [17|18|__|__]

この簡単な例では、1ページを保存しています。削除がインデックスの順序が正しくない挿入と同様の効果を持つ方法を簡単に確認できます。

緩和

データがインデックスの順序に対してかなりランダムな順序になると予想している場合はFILLFACTOR、インデックスを作成または再構築するときにこのオプションを使用して、SQL Serverにギャップを人為的に残して後で埋めるように指示できます-長期的にはページ分割を減らしますが、最初はより多くのスペースを取ります。もちろん、この値を間違って取得すると、状況を改善するのではなく、事態をさらに悪化させる可能性があるため、注意して処理してください。

特にクラスター化インデックスでのページ分割は、挿入/更新のパフォーマンスに影響を与える可能性があるFILLFACTORため、書き込みアクティビティが多いデータベースでのスペース使用の問題ではなく、そのために微調整される場合があります(ただし、ほとんどのアプリでは、読み取りが書き込みよりも多い数桁の大きさで、実質的にランダムなコンテンツを持つ列にインデックスがある場合などの特定の場合を除いて、通常はfill-factorを100%のままにした方がよいでしょう。

他のビッグネームDBにも同様のオプションがあると思いますが、このレベルの制御も必要です。

更新

ALTER INDEX上記の入力を開始した後に質問に追加されたステートメントについて:インデックスが最初に構築されたとき(または最後に再構築されたとき)のオプションは同じであると想定していますが、そうでない場合、これを追加すると圧縮オプションが非常に重要になる可能性があります周りの時間。また、そのステートメントでは、fillfactorが100%ではなく85%に設定されているため、再構築後すぐに各リーフページは約15%空になります。


2
+1ページのFILLFACTORが100%未満の場合、たとえば、ページのFILLFACTORが50%の場合、新しく再構築されたクラスター化インデックス(テーブル)は、100%のFILLFACTORで再構築された場合の2倍の大きさになります。
マックスヴァーノン

6

インデックスを再構築すると、文字どおりすべてのデータが新しいページに配置されます。再構築の前に、列を削除したり、可変幅の列を更新してデータを少なくしたり、固定幅の列サイズを変更したり、多くの行を削除したりするなど、多くのデータを削除したと思います。これらの操作のいずれでも、ページに多くの空スペースが残る可能性があり、再構築するまで再利用されません。の「データ」列sp_spaceusedは実際のデータではなく、データの保存に使用された8Kページの数を測定しています。再構築により、これらのページはよりいっぱいになり、同じ量のデータがより少ない数のページに収まっています。


5

sp_spaceusedストアドプロシージャは、データベース内の行の合計culmulativeサイズを調べていません。データに割り当てられたエクステントの累積サイズでそのデータを保持するために割り当てられたスペースのサイズを報告しています。

削除された多くの行などから利用可能なかなりの空き領域がある場合、クラスター化インデックスの再構築により、ページとエクステントの領域が圧縮され、パフォーマンス上の理由から効率が向上します(つまり、より小さくなります)。

そのため、データは破棄されるべきではありませんでしたが、再構築プロセスにより、データページに埋め込まれた空き領域が再び利用可能になりました。

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