SQL Serverのカバーと単一のインデックスの重複
-
08-10-2019 - |
質問
SQL Server(またはそのことについてはRDBMS)でのインデックス作成のためのベストプラクティスに関する質問があります。次の表を取ります。
ProfileID int
Text nvarchar(50)
ProfileID
に結合されます Profile
テーブル。各プロファイルについて、それぞれ Text
ユニークでなければなりません。したがって、両方の列にプライマリカバーキーを置きます。罰金。
しかし、私はまた、上記のテーブルを照会できるようにしたいと思っています ProfileID
. 。それで、私もインデックスをかけました ProfileID
それも。
これは、重複するインデックスがあることを意味します。カバーインデックスが既にあるため、これが完全な廃棄物なのか、それともカバーインデックスが2つの列のハッシュになるので正しいのかはわかりません(または、カバーインデックスを誤解していますか)?
編集:
順序でインデックスを作成しました (ProfileID, Text)
. 。引数のために、3つの列a、b、およびcがあり、3つの列A、b、およびcがありました。 「b」、または「c」、または「bとc」?
解決
インデックスオン (ProfileID, Text)
(この順序で)はインデックスです ProfileID
同じように。
あなたはまだ追加のインデックスを作成したいかもしれません ProfileID
あなたがより大きくしたい場合にのみ SELECT
関与しないクエリのパフォーマンス Text
.
ただし、これには2つの欠点があります。
2つのインデックスを維持するには、より多くのリソースとパフォーマンスが必要です
DML
クエリ(INSERT
,UPDATE
,DELETE
)苦しむ可能性があります2つのタイプのクエリを組み合わせると、両方のインデックスがキャッシュを占有し、単一のインデックスよりもキャッシュミスが多い場合があります。
テーブルが両方のインデックスとともにキャッシュに収まるほど小さい場合、それは問題ではありません。
カバーインデックスは、2つの列のハッシュになります(または、カバーインデックスを誤解していますか)?
この方法で、本当にカバーするインデックスが作成されます。
CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)
こちらです、 Text
インデックスのリーフレベルノードにのみ保存されます。
ただし、必要なので UNIQUE
インデックス、両方の列がキーの一部である必要があります。ノードは辞書編成的にソートされています ProfileID
それから Text
.
順序でインデックスを作成しました(ProfileID、テキスト)。引数のために、3つの列a、b、およびcがあり、3つの列A、b、およびcがありました。 「b」、または「c」、または「bとc」?
CREATE INDEX ix_mytable_a_b_c ON mytable (a, b, c)
SELECT a, b, с
FROM mytable
WHERE a = 1
-- Index lookup, no table lookup. a is leading
SELECT a, b, с
FROM mytable
WHERE a = 1
AND b = 1
-- Index lookup, no table lookup. (a, b) are leading.
SELECT a, b, с
FROM mytable
WHERE b = 1
-- Index full scan (`b` is not leading), no table lookup
SELECT a, b, с
FROM mytable
WHERE c = 1
-- Index full scan (`c` is not leading), no table lookup
SELECT a, b, с, d
FROM mytable
WHERE a = 1
-- Index lookup, table tookup (d is not a part of the index).
SELECT a, b, с, d
FROM mytable
WHERE b = 1
-- Table full scan (there is no point in using index at all, neither for lookup nor for covering).