I have a recursive query which executes very fast if the WHERE
clause contains a constant but becomes very slow if I replace the constant with a parameter havin
As Martin suggested in a comment under the question, the problem is that SQL server does not push down properly the predicate from the WHERE clause - see the link in his comment.
I ended up with creating a user defined table-valued function and use it with the CROSS APPLY operator for creating the view.
Let's see the solution itself.
User Defined Table-valued Function
CREATE FUNCTION [dbo].[TestFunction] (@Id INT)
RETURNS TABLE
AS
RETURN
(
WITH
Hierarchy (Id, ParentId, Data, Depth)
AS(
SELECT Id, ParentId, NULL AS Data, 0 AS Depth FROM Test Where Id = @Id
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
)
View
CREATE VIEW [dbo].[TestView]
AS
SELECT t.Id, t.ParentId, f.Data, f.Depth
FROM
Test AS t
CROSS APPLY TestFunction(Id) as f
Query with constant
SELECT * FROM TestView WHERE Id = 69
Query with parameter
DECLARE @Id INT
SELECT @Id = 69
SELECT * FROM TestView WHERE Id = @Id
The query with the parmater executes basically as fast as the query with the constant.
Thank You Martin and for the others as well!