与此问题类似,但给出的建议似乎不适用于我的情况
我有一个看起来像这样的#temp 表:
CREATE TABLE #C (
OutA int,
OutB int,
OutC int,
SortD float,
PartE nvarchar(400),
PartF nvarchar(400)
)
现在它包含大约。10M 行,尽管我需要它来处理比这更多的行(我已经限制了它,以便检查查询计划不会花一整天的时间!)
该表具有以下索引和统计信息:
CREATE INDEX B ON #C(SortD DESC) INCLUDE (OutA, OutB, OutC)
CREATE INDEX C ON #C(PartE, SortD DESC) INCLUDE (OutA, OutB, OutC)
CREATE INDEX D ON #C(PartF, SortD DESC) INCLUDE (OutA, OutB, OutC)
CREATE STATISTICS E ON #C (OutA);
CREATE STATISTICS F ON #C (OutB);
CREATE STATISTICS G ON #C (OutC);
(我不确定为什么需要统计数据,这似乎对计划没有影响,但是当它们丢失时它会抱怨)
最后,我尝试使用不同的分区但相同的排序顺序在此数据上创建 3 个不同的排名
SELECT OutA,
OutB,
OutC,
RANK() OVER (ORDER BY SortD DESC) AS [Rank1],
RANK() OVER (PARTITION BY PartE ORDER BY SortD DESC) AS [Rank2],
RANK() OVER (PARTITION BY PartF ORDER BY SortD DESC) AS [Rank3]
INTO #Junk1
FROM #C
这需要将近 2 分钟才能运行。
如您所见,此计划中有多种昂贵的种类。根据链接的问题,我创建的索引应该可以在这里使用,但它们没有被使用。
如果我改为创建 3 个单独的查询,每个等级 1 个,在这种情况下,索引将按预期使用。我确实尝试利用它并加入 3 个查询结果以产生相同的输出,但这实际上总体上花费了稍微长一点的时间
我还尝试修改索引以包含分区列,如下所示:
CREATE INDEX B ON #C(SortD DESC) INCLUDE (OutA, OutB, OutC, PartE, PartF)
CREATE INDEX C ON #C(PartE, SortD DESC) INCLUDE (OutA, OutB, OutC, PartF)
CREATE INDEX D ON #C(PartF, SortD DESC) INCLUDE (OutA, OutB, OutC, PartE)
通过从表扫描更改为索引扫描(B),这成功地删除了第一个(最右边的)排序。但其他种类仍然存在
为什么需要多个排名时不使用索引?我怎样才能消除昂贵的种类?