我有一个递归查询,如果WHERE
子句包含一个常量,但如果我用具有相同值的参数替换该常量,则会变得非常慢。
查询 #1 - 使用常量
;WITH Hierarchy (Id, ParentId, Data, Depth)
AS
( SELECT Id, ParentId, NULL AS Data, 0 AS Depth
FROM Test
UNION ALL
SELECT h.Id, t.ParentId, COALESCE(h.Data, t.Data), Depth + 1 AS Depth
FROM Hierarchy h
INNER JOIN Test t ON t.Id = h.ParentId
)
SELECT *
FROM Hierarchy
WHERE Id = 69
查询 #2 - 带参数
DECLARE @Id INT
SELECT @Id = 69
;WITH Hierarchy (Id, ParentId, Data, Depth)
AS
( SELECT Id, ParentId, NULL AS Data, 0 AS Depth
FROM Test
UNION ALL
SELECT h.Id, t.ParentId, COALESCE(h.Data, t.Data), Depth + 1 AS Depth
FROM Hierarchy h
INNER JOIN Test t ON t.Id = h.ParentId
)
SELECT *
FROM Hierarchy
WHERE Id = @Id
如果表有 50,000 行,则带有常量的查询运行 10 毫秒,带有参数的查询运行 30 秒(慢 3,000 倍)。
移动最后一个不是一个选项WHERE
子句到递归的锚定义,因为我想使用查询来创建视图(没有最后一个WHERE
)。从视图中选择将具有WHERE
子句(WHERE Id = @Id
) - 由于实体框架,我需要这个,但那是另一个故事了。
任何人都可以建议一种方法来强制查询#2(带有参数)使用与查询#1(带有常量)相同的查询计划吗?
我已经尝试过使用索引,但这没有帮助。
如果有人愿意,我也可以发布表定义和一些示例数据。
我正在使用 SQL 2008 R2。
提前谢谢你的帮助!
执行计划 - 查询 #1 - 具有常量
执行计划 - 查询 #2 - 带参数