非クラスター化インデックス-キーと非キー


8

私はこれらの概念を正しく理解していることを確認したいだけなので、フィードバックがあれば大歓迎です。

これは、試行錯誤のプロセスとMSDNドキュメントを読んで、最適化したばかりのクエリからの私の理論です。

クエリ

DECLARE @pic_id int
SET pic_id = 1

SELECT ROW_NUMBER() OVER (ORDER BY pic_date desc) AS row_num, *
FROM tbl_pics
WHERE deleted = 0 AND map_id = 1 AND (hidden = 0 OR pic_id = @pic_id)

インデックス

CREATE NONCLUSTERED INDEX [IX_tbl_pics] ON [dbo].[tbl_pics] 
(
    [map_id] ASC,
    [deleted] ASC,
    [pic_date] DESC
)
INCLUDE ( [hidden], [pic_id] )

pic_idにはPKインデックスもあります。

その理論

キー列は、WHERE句(ORの状況では使用されません)またはORDER BYで使用されるため、そうです。

非キー(INCLUDE)列はWHEREで使用されるためですが、ORシナリオで使用されるため、キー列にすることはできません(パフォーマンスを向上させることはできません)。

これらの推定は正しいですか?そうでない場合、何が欠けていますか?

ありがとう!

回答:


8

クエリオプティマイザーにクエリに応答できるプランを作成するように依頼しています。

SELECT *
FROM tbl_pics
WHERE deleted = 0 AND map_id = 1 AND hidden = 0;

残りは綿毛です(を含むOR pic_id = @pic_id)。これは、関係する述語(私は確信しているの低い選択性の保証、表スキャンになりますdeletedhidden0/1であり、map_ip私はそれが重要な影響を持っている疑い)。クエリを保存できる唯一の述語はpic_id = @pic_id、それをOR条件に置くことによって、あなたがそのチャンスを殺したことです。現実的には、セカンダリインデックスはそれを助けることができません。ほとんどの場合、ROW_NUMBERを追加すると並べ替えが行われますが、実際の被害はスキャンです。

これは失われた原因です。現実的な要件を考え出す。


6

主キーもクラスター化インデックスですか?その場合INCLUDE (pic_id)、一意のクラスター化インデックスが非クラスター化インデックスのブックマークとして既に使用されているため、理由はありません。

ORについて話している限り、これは事実上WHEREの2番目の部分ですが、最初の選択性に依存してほとんどの作業を行います(INCLUDEに依存してテーブル)。

しかし、そこに*があると、とにかくテーブルに行かなければならない場合があります。

一方、負荷をあまり考慮せずにこのクエリを頻繁に使用しない限り、単一のクエリに基づいてインデックスを設計していない可能性があります。それでも、実行計画を見ていても害はありません。

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