使用CTE优化时态表

Jon*_*han 7 sql t-sql sql-server common-table-expression sql-server-2017

我创建时态表以设置级别:

CREATE TABLE [#DesignLvl]
(
    [DesignKey] INT,
    [DesignLevel] INT
);

WITH RCTE AS 
(
    SELECT
        *,
        1 AS [Lvl]
    FROM 
        [Design]
    WHERE 
        [ParentDesignKey] IS NULL

    UNION ALL

    SELECT
        [D].*,
        [Lvl] + 1 AS [Lvl]
    FROM 
        [dbo].[Design] AS [D]
    INNER JOIN 
        [RCTE] AS [rc] ON [rc].[DesignKey] = [D].[ParentDesignKey]
)
INSERT INTO [#DesignLvl]
    SELECT
        [DesignKey], [Lvl]
    FROM 
        [RCTE]
Run Code Online (Sandbox Code Playgroud)

创建后,在非常大的查询中将LEFT JOIN用作:

SELECT... 
FROM.. 
LEFT JOIN [#DesignLvl] AS [dl] ON d.DesignKey = dl.DesignKey
WHERE ...
Run Code Online (Sandbox Code Playgroud)

该查询有效,但是性能下降并且查询现在太慢。有什么方法可以优化此表?

CTE执行计划

在此处输入图片说明

我尝试将CLUSTERED索引添加为:

CREATE TABLE [#DesignLvl]
(
    [DesignKey] INT,
    [DesignLevel] INT
);

CREATE CLUSTERED INDEX ix_DesignLvl 
    ON [#DesignLvl] ([DesignKey], [DesignLevel]);
Run Code Online (Sandbox Code Playgroud)

也可以尝试:

    CREATE TABLE [#DesignLvl] 
( [DesignKey] INT INDEX IX1 CLUSTERED ,
 [DesignLevel] INT INDEX IX2 NONCLUSTERED );
Run Code Online (Sandbox Code Playgroud)

但是我得到了相同的结果,执行花费了很长时间

Lui*_*res 2

根据我在本文中发布的测试,基于集合的循环可以比递归 CTE 提高性能。

DECLARE @DesignLevel int = 0;

INSERT INTO [#DesignLvl]
SELECT [DesignKey], 1
FROM [RCTE];

WHILE @@ROWCOUNT > 0
BEGIN
    SET @DesignLevel += 1;

    INSERT INTO [#DesignLvl]
    SELECT [D].[DesignKey], dl.DesignLevel
    FROM [dbo].[Design] AS [D]
    JOIN [#DesignLvl] AS [dl] ON [dl].[DesignKey] = [D].[ParentDesignKey]
    WHERE dl.DesignLevel = @DesignLevel;
END;
Run Code Online (Sandbox Code Playgroud)