sql - 如何使用递归 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 以来,我已经忘记了这个术语,我需要去刷新我的记忆)。
解决方案
推荐阅读
- python - 从 CSV 中分离字符串并打印它们
- java-6 - 如何在 Java 6 中使用 DirectoryStream?
- kotlin - Kotlin 中类名后的方括号
- jhipster - 在 Linux 机器上运行 Jhipster 生成的战争时出错
- matlab - 失败的 MATLAB 许可证是 try/catch 异常吗?
- javascript - 访问控制器角度js中的状态参数对象
- android - [Android][Kotlin] 使用 AudioRecord 实现带通滤波器并写入 16BIT PCM 文件
- javascript - 每次更改组件的状态时,图表都会再次绘制
- google-cloud-platform - 我对 DataFusion 数据管道有疑问
- laravel - Amazon SES 不发送到所有电子邮件,仅批准