我有一个视图,该视图使用递归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以来,我已经忘记了该术语。时间之前,我需要去刷新我的记忆)。