web-dev-qa-db-ja.com

非クラスター化インデックスのインクルード列として主キーを指定することに違いはありますか?

非クラスター化インデックスは、必要に応じてキー検索を実行できるように、テーブルの主キーへの参照を本質的に格納しませんか?非クラスター化インデックスを作成しますか?

副次的な質問、なぜ非クラスター化インデックスがデフォルトでクラスター化インデックスフィールドではなくプライマリキーを格納してテーブルでキールックアップを行うのですか?...プライマリーキーがクラスター化インデックスではない場合、遅くなりませんか?キールックアップが発生するのに対して、クラスター化インデックスが格納されている場合は、そのようにルックアップを実行できますか?

5
J.D.

非クラスター化インデックスには、ベーステーブルに戻る行ロケーターが含まれています。

これは、クラスター化インデックスまたはヒープの物理RID(ファイル/ページ/スロット)を持つ行ストアテーブルのクラスター化インデックスキーです。

したがって、(これらが異なる場合に)主キーを使用すると仮定した質問の部分は、根拠のないものです。

行ロケーターは、一意でない非クラスター化インデックスのキーに追加され、一意として宣言された非クラスター化インデックスの包含列として追加されます。

includedの場合にこれを明示的に指定しても、パフォーマンス上の利点はありません。暗黙的にキーに追加される場合、クエリがasc/desc方向または複数列の順序付けによって暗黙的に得られるものよりもメリットがある場合、明示的にこれを行う必要がある場合があります。 。

暗黙的な動作に慣れていない開発者がコードを読みやすくするため、または将来的にクラスター化インデックスの定義が変更される場合でも、クエリでインデックス内のこれらの列が引き続き必要になる場合は、明示的にすることをお勧めします。

コメントのフォローアップ質問について

これは、主キーが選択リストにある場合、主キーの非クラスター化インデックスから(主キーがクラスター化インデックスではない場合)キー検索が実行される可能性があることを意味しますか?

はい、以下で確認できます。

CREATE TABLE #T
(
PK INT PRIMARY KEY NONCLUSTERED,
CI INT INDEX CIX CLUSTERED,
OtherCol INT INDEX NCIX NONCLUSTERED
)

SELECT *
FROM #T WITH (FORCESEEK)
WHERE OtherCol = 10

enter image description here

  1. NCIXでのシークの出力リストはUniq1001, CI, OtherColです
  2. CI, Uniq1001の値は、クラスター化インデックスにシークするためにルックアップによって使用されます...
  3. ...そしてPKの値がそのルックアップから返されます。

Uniq1001について不思議に思っている場合、これは、クラスター化インデックスが一意であると宣言されていないため、システムによって暗黙的に追加され、一意化子として機能するクラスター化インデックスキーの一部です。 CIの値に対して重複が存在/存在する行を除いて、空です。

12
Martin Smith