(ア)
CREATE NONCLUSTERED INDEX foo ON dbo.my_table(B, C DESC) INCLUDE (A);
(ロ)
A はWHERE
orORDER BY
にないので、おそらく d 列のリストにあれば十分ですINCLUDE
。なぜなら、それは単に「乗り物に沿って」いるだけであり、キーの一部である必要はないからです。
(ハ)
これ以上の文脈なしに答えることは不可能です。サブクエリだけを含めて、表示されない外部クエリについて尋ねるのはなぜですか?
@Quassnoiとの進行中の会話に関してEDIT 、非クラスター化インデックスの末尾の列のソート方向が、特定のクエリで使用される計画に大きな違いをもたらす可能性があることをすばやく示したかっただけです。次の不自然な例を見てみましょう。
CREATE TABLE dbo.foo1(A INT, B INT, C INT);
CREATE NONCLUSTERED INDEX foo1x ON dbo.foo1(B, C) INCLUDE(A);
CREATE TABLE dbo.foo2(A INT, B INT, C INT);
CREATE NONCLUSTERED INDEX foo2x ON dbo.foo2(B, C DESC) INCLUDE(A);
INSERT dbo.foo1 SELECT TOP (500000) c.[object_id], c.[object_id], -1*c.[object_id]
FROM sys.all_columns AS c CROSS JOIN sys.all_objects
ORDER BY c.[object_id];
INSERT dbo.foo2 SELECT TOP (500000) c.[object_id], c.[object_id], -1*c.[object_id]
FROM sys.all_columns AS c CROSS JOIN sys.all_objects
ORDER BY c.[object_id];
それでは、これら 2 つの提案されたクエリを実行して、プランを調べてみましょう。
SELECT A
FROM (
SELECT A, ROW_NUMBER() OVER (PARTITION BY B ORDER BY C DESC) RN
FROM dbo.foo1
) q
WHERE rn = 1;
SELECT A
FROM (
SELECT A, ROW_NUMBER() OVER (PARTITION BY B ORDER BY C DESC) RN
FROM dbo.foo2
) q
WHERE rn = 1;
dbo.foo1 (C は ASC) に対するクエリのプランは次のとおりです。


そして、私が言及した種類:

dbo.foo2 (C は DESC) に対するクエリのプランは次のとおりです。


ここで、内部クエリに WHERE 句を追加すると (たとえば、WHERE B = -1024577103)、プランはより類似したものになります。ただし、これは、PARTITION BY が不要であること、および外部クエリを B のその値に制限するために何らかのマッチングが必要であることも意味します。ただし、質問の特定のクエリでは、インデックスの各列の並べ替え方向が計画にほとんど影響を与えない可能性がありますが、これは同じインデックスを使用できるすべてのクエリに当てはまるわけではありません。