将 INDEX 添加到 CTE

发布于 2024-09-28 07:21:16 字数 37 浏览 3 评论 0原文

我可以将 INDEX 添加到公用表表达式 (CTE) 中吗?

Can I add an INDEX to a Common Table Expression (CTE)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

≈。彩虹 2024-10-05 07:21:16

我也有过同样的要求。无法将索引添加到 CTE。然而,在 CTE select 中,在连接字段上添加 ORDER BY 子句将执行时间从 20 分钟或更长减少到 10 秒以下。

(您还需要添加 SELECT TOP 100 PERCENT 以允许在 CTE 选择中使用 ORDER BY。)

[编辑以添加下面评论中的解释引用]:
如果 CTE 中有 DISTINCT,则 TOP 100 PERCENT 不起作用。这种作弊方法始终可用:在选择中根本不需要 TOP,将 ORDER BY 语句更改为:
排序依据 [Blah] 偏移 0 行

I have had the same requirement. Indexes can not be added to a CTE. However, in the CTE select adding an ORDER BY clause on the joined fields reduced the execution time from 20 minutes or more to under 10 seconds.

(You need to also ADD SELECT TOP 100 PERCENT to allow an ORDER BY in a CTE select.)

[edit to add paraphrased quote from a comment below]:
If you have DISTINCT in the CTE then TOP 100 PERCENT doesn't work. This cheater method is always available: without needing TOP at all in the select, alter the ORDER BY statement to read:
ORDER BY [Blah] OFFSET 0 ROWS

黯然#的苍凉 2024-10-05 07:21:16

不可以

。CTE 是临时的“内联”视图 - 您无法向此类构造添加索引。

如果需要索引,请使用 CTE 的 SELECT 创建常规视图,并将其设为索引视图(通过向视图添加聚集索引)。您需要遵守此处列出的一组规则:创建索引视图< /a>.

No.

A CTE is a temporary, "inline" view - you cannot add an index to such a construct.

If you need an index, create a regular view with the SELECT of your CTE, and make it an indexed view (by adding a clustered index to the view). You'll need to obey a set of rules outlined here: Creating an Indexed View.

红颜悴 2024-10-05 07:21:16

您无法为 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 

在上面的查询中,由于 GROUP BYa JOIN b 无法使用 t.myname 上的索引。

另一方面,

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 上的索引。

You cannot index a CTE, but the approach is that the CTE can make use of the underlying indexes.

WITH cte AS (
    SELECT myname, SUM(Qty) FROM t GROUP BY myname
)
SELECT *
FROM t a JOIN cte b ON a.myname=b.myname 

In the above query, a JOIN b cannot make use of an index on t.myname because of the GROUP BY.

On the other hand,

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 

In the latter query, a JOIN b can make use of an index on t.myname.

巡山小妖精 2024-10-05 07:21:16

/* 下面的构造将我的查询时间从 2 分钟减少到 4 秒 */

WITH First_cte AS(
    SELECT Field1, Field2, etc
    FROM etc
    ORDER BY Field1, Field2 OFFSET 0 ROWS
),
Second_cte AS(
    SELECT Field1, Field2, etc
    FROM etc
    ORDER BY Field1, Field2 OFFSET 0 ROWS
)
SELECT
    First_cte.Field1, First_cte.Field2, etc
    FROM First_cte
    INNER JOIN Second_cte
        ON Second_cte.Field1 = First_cte.Field1
        AND Second_cte.Field2 = First_cte.Field2
    WHERE Second_cte.Field3 <> First_cte.Field3`

/* The Below construct reduced my query from 2 minutes to 4 seconds */

WITH First_cte AS(
    SELECT Field1, Field2, etc
    FROM etc
    ORDER BY Field1, Field2 OFFSET 0 ROWS
),
Second_cte AS(
    SELECT Field1, Field2, etc
    FROM etc
    ORDER BY Field1, Field2 OFFSET 0 ROWS
)
SELECT
    First_cte.Field1, First_cte.Field2, etc
    FROM First_cte
    INNER JOIN Second_cte
        ON Second_cte.Field1 = First_cte.Field1
        AND Second_cte.Field2 = First_cte.Field2
    WHERE Second_cte.Field3 <> First_cte.Field3`
以歌曲疗慰 2024-10-05 07:21:16

另一种技术是插入临时表而不是使用 CTE
然后,您可以向临时表添加索引

。通过执行此操作,我将 9 分钟的查询减少到 3 秒的查询。

有些人可能强烈反对临时表。

对于我们其他人来说,试图让事情正常运转……需要考虑一些事情。

(我确实尝试了前 100000 个... order by)我没有意识到时间减少。

Another technique is to insert into a temp table instead of using a CTE
You can then add an index to the temp table

I reduced a 9min query to a 3 sec query by doing this.

Some may be religiously opposed to temp tables.

for the rest of us trying to get things working... something to consider.

( I did try the top 100000 ... order by) I did not realize a time reduction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文