将INDEX添加到CTE

时间:2010-10-22 10:31:50

标签: sql-server-2008 common-table-expression

应该是一个非常直截了当的问题。我可以将INDEX添加到公用表表达式(CTE)吗?

4 个答案:

答案 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 bt.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更快。