У меня есть рекурсивный запрос, который выполняется очень быстро, если предложение 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
) - мне нужно это из-за Entity Framework, но это еще одна история.
Может ли кто-нибудь предложить способ заставить запрос №2 (с параметром) использовать тот же план запроса, что и запрос №1 (с константой)?
Я уже пробовал играть с индексами, но это не помогло.
Если кому-то захочется, я могу опубликовать определение таблицы и некоторые примеры данных. Я использую SQL 2008 R2.
Спасибо за вашу помощь заранее!
План выполнения - Запрос №1 - с константой
План выполнения - Запрос № 2 - с параметром