web-dev-qa-db-ja.com

SQL Serverのクラスター化インデックスの高断片化

主キーとして整数(4バイト)のテーブルがあります。アイデンティティとして定義されます。これはクラスター化インデックスでもあります。

インサートは完全に正常に機能しています。 2000行を挿入すると、断片化は約4%になります。

ただし、各レコードは少なくとも3回更新されます。これにより、99%を超えるこのクラスター化インデックスの断片化が生成されます(既定のフィルファクターを使用)。

または、私がテストした他のFILL FACTORと一緒に:-クラスターインデックスにFILL FACTORを80に設定(フラグメンテーション> 98%)-クラスターインデックスにFILLファクター50を設定(FRAMMENTATION> 94%)

だから、これはあまり役に立たないようです...

2000の挿入(および3つ以上の更新)を使用して、新しく作成したテーブルで各フィルファクタ設定をテストしました

クエリに主キーを含まない選択または更新はありません。

なぜこのインデックスが非常に高い断片化を持っているのか誰かに考えがありますか?

更新はADO.NETを介して行われます。これは生成されたコマンドです(SQLプロファイラーによってトレースされます)。

exec sp_executesql N'UPDATE MyTable SET MyValue = @MyValue WHERE MyId = @MyId',
N'@MyValue varchar(50),@MyId int',@MyValue='This is some random value',@MyId=1234

他の更新は同じパターンに従います(他の値を更新しますが、常に@MyIdパラメーターを提供します)

ご協力ありがとうございました :)

6
Nicholas

FILLFACTOR は、通常の操作ではなく、インデックスを構築または再構築する場合にのみ適用されます。通常の操作では、常にページを100%まで埋めようとします。

可変幅の行を挿入し、その行を長くなるように更新すると、同じページに変更後イメージを保存するのに十分な追加スペースがない場合、その行はページに収まりません。十分なスペースがない場合、これによりページ分割が発生します。これは、必要なスペースを作成するプロセスです。

ページ分割について少し誤解を招くのは、パフォーマンスカウンターがそれらすべてをカウントしても、「良い分割」と「悪い分割」があることです。

  • よい分割は、新しい行がインデックスのendに追加されたときです。たとえば、INSERTsの最初のバッチを実行したときのようになります。 。新しい行が最後のページに収まらないため、ストレージエンジンは新しいページを割り当て、それを論理的に最後のインデックスページに接続する必要があります。新しいページはおそらく、最後のインデックスページの後に物理的に存在します。

  • 不適切な分割は、インデックスのmiddleにページを挿入する必要がある場合です。新しいページは、両側で論理的にインデックス構造に接続されますが、それらのページに隣接する物理的な順序で(おそらく)存在しない可能性があります。

断片化は論理的順序と物理的順序の不一致であり、ほとんどの場合、不良タイプのページ分割のみが断片化を引き起こします。

既存の行のサイズを大きくしているため、ページ分割のタイプが不適切になり、断片化の数値が高くなっています。

正確なプロセスが何であるか、最終的にこの表に含まれる行数は不明です。それが1回限りのポピュレーションのようなものである場合は、完全なポピュレーションプロセスを実行してから、向きを変えて100%FILLFACTORでクラスター化インデックスを再構築します。

このプロセスが継続的に発生する場合は、次のようにしてスペースを「事前に割り当てる」ことができます。テーブルにダミーの可変幅の列を追加し、INSERTの最大長に設定してから、最初のUPDATE、実際の値を更新するときにダミー値をNULLに設定します。この方法では、すべてのデータ値が飛び交うため、おそらくロギングメカニズムにオーバーヘッドが追加されます。

ただし、一般的には、これらの要素のallがtrueの場合にのみ、フラグメント化に注意する必要があります。

  • インデックスが十分に大きいため、ページ(エクステント)をランダムに読み取るのが遅すぎる(「遅すぎる」の意味について独自の定義を選択してください)。
  • インデックスがスキャンされます
  • インデックスページ(エクステント)はディスクから物理的に読み取られます(つまり、それらはまだバッファープールにありません)。
  • ストレージサブシステムは、ランダムな読み取り(つまり、スピンドルベース、、およびのバイトがキャッシュから取得されない)の処理が不十分です。

ただし、多かれ少なかれ状況をチェックするために、確実なインデックスメンテナンスソリューションを導入することをお勧めします。このサイトに関する推奨事項を検索できます。

15
Jon Seigel

新しいレコードが適切なデフォルトサイズで作成されていることも確認する価値があります。

レコードごとに10バイトを割り当てる新しいページが不要で、アプリケーションが100バイトに相当するものでページを作成したくない場合。これは、ページ分割を右/中央/左に強制することになります。平均レコードサイズを見つけて、おおよそのサイズのデフォルト値を設定することで回避できます。

1
John Alan