如何避免带有递归CTE查询的紧急假脱机?

时间:2019-04-23 17:03:29

标签: sql sql-server tsql

我有一个视图,该视图使用递归CTE为我提供任何给定记录的后代列表(SQL Server 2014):

CREATE VIEW descendants AS
    WITH results AS (
        SELECT  tbl.id,
                tbl.id AS ancestorId
        FROM    tbl
        UNION ALL
        SELECT  tbl.id,
                d.ancestorId
        FROM    tbl
                INNER JOIN results AS d ON d.id = tbl.parentId
    )
    SELECT * FROM results;

这很漂亮。这样的查询可以非常快速地返回匹配的记录ID 所有后代记录ID:

SELECT * FROM descendants WHERE ancestorId = 22;

但是,一旦我使用了变量,执行时间就会从0.1秒变为10秒!

DECLARE @p int;
SET @p = 22;
SELECT * FROM descendants WHERE ancestorId = @p;

计划完全不同

快速结果,使用文字值: Plan using a literal value

结果,使用具有相同值的变量: Plan using a variable value

邪恶的根源似乎是热切的线轴。

如何避免这种情况?我想不出很多用例,这对查询是有利的。

编辑:我看到了一些类似的问题,但是它们似乎集中在万圣节问题上,该问题不在此处。既然是评论,而不是答案,我会提到OPTION(RECOMPILE)的建议非常有效,并且我正在考虑更改“锚定”(自从我长期使用递归CTE以来,我已经忘记了该术语。时间之前,我需要去刷新我的记忆)。

0 个答案:

没有答案