(一种)
CREATE NONCLUSTERED INDEX foo ON dbo.my_table(B, C DESC) INCLUDE (A);
(乙)
由于 A 不在WHERE
orORDER BY
中,因此在 d 列的列表中可能就足够了INCLUDE
,因为它只是“顺路”而不需要成为键的一部分。
(C)
没有更多上下文无法回答。为什么只包含子查询然后询问我们看不到的外部查询?
编辑关于与@Quassnoi 正在进行的对话,我只是想快速证明非聚集索引中尾随列的排序方向可以对特定查询使用的计划产生很大影响。让我们举一个人为的例子:
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];
现在,让我们运行这两个提议的查询并检查计划:
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 的值。但是我的观点仍然是,虽然对于问题中的特定查询,索引中每一列的排序方向可能对计划影响不大,但对于所有可以使用相同索引的查询来说,情况并非如此。