应该是一个非常直截了当的问题。我可以将INDEX添加到公用表表达式(CTE)吗?
答案 0 :(得分:55)
我有同样的要求。索引无法添加到CTE。但是,在CTE选择中,在连接字段上添加 ORDER BY 子句会将执行时间从20分钟或更长时间减少到10秒以下。
(您还需要添加SELECT TOP 100 PERCENT以允许CTE选择中的ORDER BY。)
[编辑以添加下面评论中的释义引用]:
如果您在CTE中有DISTINCT,则TOP 100 PERCENT不起作用。这种骗子方法始终可用:在选择中根本不需要TOP,将ORDER BY语句改为:
ORDER BY [Blah] OFFSET 0 ROWS
答案 1 :(得分:19)
没有
CTE是一种临时的“内联”视图 - 您无法为此类构造添加索引。
如果需要索引,请使用CTE的SELECT创建常规视图,并使其成为索引视图(通过向视图添加聚簇索引)。您需要遵守此处列出的一组规则:Creating an Indexed View。
答案 2 :(得分:1)
您不能为CTE建立索引,但是方法是CTE可以利用基础索引。
WITH cte AS (
SELECT myname, SUM(Qty) FROM t GROUP BY myname
)
SELECT *
FROM t a JOIN cte b ON a.myname=b.myname
在上述查询中,由于a JOIN b
,t.myname
无法使用GROUP BY
上的索引。
另一方面,
WITH cte AS (
SELECT myname, SUM(Qty) OVER (PARTITION BY myname) AS SumQty,
ROW_NUMBER() OVER (PARTITION BY myname ORDER BY myname, Qty) AS n
)
SELECT * FROM t a JOIN cte b ON a.myname=b.myname AND b.n=1
在后一个查询中,a JOIN b
可以使用t.myname
上的索引。
答案 3 :(得分:-2)
@B H - 为了解决使用TOP 100%或TOP 1000000的DISTINCT问题,您始终可以使用GROUP BY。服务于同一目的,有时比DISTINCT更快。