递归 CTE 性能不佳

Posted

技术标签:

【中文标题】递归 CTE 性能不佳【英文标题】:Bad performance of recursive CTE 【发布时间】:2020-09-23 18:05:53 【问题描述】:

我有一个 [LOCATION] 表,它是一个自引用表。

一个位置可以有一个 [PARENT_ID](id 或 NULL)。 一个位置可以是 [ENABLED](0 或 1)。

我的视图的目的是列出每个位置,并添加一个新列 [ENABLE_IN_HIERARCHY]。 这个新专栏必须说明: -1 如果位置已启用并且其所有父位置均已启用 -0 如果位置未启用其父位置之一未启用

我的 T-SQL 视图做得正确,但我遇到了性能问题:

WITH LOCATION_CTE ([ID], [DISPLAY_NAME], [PARENT_ID], [ENABLED],
  [ENABLED_IN_HIERARCHY])
AS (
    SELECT [ID], [DISPLAY_NAME], [PARENT_ID], [ENABLED], [ENABLED]
    FROM [LOCATION]
    WHERE [PARENT_ID] IS NULL

    UNION ALL

    SELECT l.[ID], l.[DISPLAY_NAME], l.[PARENT_ID], l.[ENABLED], 
      CAST(CASE WHEN l.[ENABLED] = 1 AND LOCATION_CTE.[ENABLED_IN_HIERARCHY] = 1 
                THEN 1 ELSE 0 
                END AS BIT) AS [ENABLED_IN_HIERARCHY]
    FROM [LOCATION] l
    INNER JOIN LOCATION_CTE ON LOCATION_CTE.[ID] = l.[PARENT_ID]
    )
SELECT *
FROM LOCATION_CTE

有没有更好的方法来构建这个查询?

【问题讨论】:

如果您能发布一些示例数据、表结构和预期结果会有所帮助 这张表有多少行?可以分享一下它的结构吗?有没有索引? 【参考方案1】:

为了让这个视图更快,你需要有索引:

create index ix1 on [LOCATION] ([PARENT_ID]);

否则它可能会很慢,特别是如果表有很多行。

【讨论】:

以上是关于递归 CTE 性能不佳的主要内容,如果未能解决你的问题,请参考以下文章

CTE 中的 SQL Server 视图导致性能不佳

递归 CTE 存在性能问题,需要建议以优化查询

sql server数据库性能优化之2-避免使用CTE公用表达式的递归by zhang502219048

Oracle 嵌套 CONNECT BY 子句导致性能不佳

哪个性能更高,CTE 或临时表?

CTE、子查询、临时表或表变量之间是不是存在性能差异?