首页 > 解决方案 > 如何使用递归 CTE 查询避免急切的假脱机?

问题描述

我有一个使用递归 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;

计划非常不同。

使用文字值的快速结果: 使用文字值进行计划

缓慢的结果,使用具有相同值的变量: 使用变量值进行计划

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

我怎样才能避免这种情况?我想不出这对查询有利的许多用例。

编辑:我见过一些类似的问题,但他们似乎专注于万圣节问题,这在这里没有发挥作用。由于它是评论,而不是答案,我会提到该OPTION(RECOMPILE)建议效果很好,我正在考虑更改“锚”(自从我很久以前第一次使用递归 CTE 以来,我已经忘记了这个术语,我需要去刷新我的记忆)。

标签: sqlsql-servertsql

解决方案


推荐阅读