2011-07-01 8 views
2

のは、私はこのようなテーブルがあるとしましょう:インデックスはすでにクラスター化された主キーをカバーしていますか?

CREATE TABLE t(
    [guid] [uniqueidentifier] NOT NULL, 
    [category] [nvarchar](400) 
    {,...other columns} 
) 

​​は私の主キーであり、クラスタ化インデックスを持っています。

は今、私は、カテゴリによってtに関連するいくつかの他のものをロールアップしています、と私はtテーブル自体を含めないようにしたいのでは、categoryと​​の両方をカバーすることを指標にしたいです。

categoryをカバーするインデックスを作成するだけで十分ですか、​​も含める必要がありますか?

私は、SQL Serverインデックスがtのページオフセットを直接指すことを期待するのではなく、単に私だろう明示的tを打つ避けるためにPK列を含める必要性を意味し​​主キーの値を参照します。これは本当ですか?

答えて

2

実際にあなたの仮定が間違っである - すべてのSQL Serverの非クラスタ化インデックスは、クラスタリングキー(単一または複数の列)を含め、いくつかの物理ページに直接ないポイントを行うのですか。

これは、ページを2つに分割する必要がある場合、または再配置する必要がある場合に、SQL Serverが多数のインデックスエントリを再編成して更新する必要をなくします。したがって、クラスタ化されていないインデックスを探していて値を見つけたら、クラスタリングキーがあり、SQL Serverは実際のデータページ(リーフページ)を取得するためにブックマーク検索(またはキー参照) 1つの行に属するデータ全体を取得します。

言い換えれば、キー列の順序に依存する状況がある場合は、(guid, category)のインデックスを作成する必要があります。もちろん、SQL Serverはクラスタ化キーの列が既に索引に入っていることを確認し、もう一度それを追加しないでください。

クラスタ化されていない単一のインデックスごとにクラスタ化キー列が含まれているという事実は、クラスタリングキーが狭く静的でユニークでなければならないもう一つの理由です。それらを広すぎるようにする(8バイトを超えるもの)ことは、膨らんで減速するための確実なレシピです。

+0

ありがとうMarc!私は実行計画を解釈して狂っていると思った。ブックマークの参照を避けるというわずかなパフォーマンス上の利点があるにもかかわらず、インデックスがページポインターで混乱してはならないということを意味します。注文についての良い点も。 – richardtallent

1

marc_sの回答と若干異なります。

(カテゴリ、guid)のカバーインデックスは、GUIDのプライマリキーソートとは異なるソートを持ちます。したがって、GUIDはキー列リストとクラスタード・インデックスへのポインターにあるため、インデックスに2回表示されることがあります。

(非キー列として)GUIDをINCLUDEすると、SQL Serverはこれを再度追加しません。

今はキー列のものをテストすることはできませんが、以前はSQL Server 2005でINCLUDEを検証しました。

関連する問題