У меня есть запрос в представлении, использующий рекурсивный cte для большого дерева, который хорошо работает при запросе с жестко закодированным числом, но не с параметром.Можно ли заставить SQL Server использовать план, который я хочу оптимизировать, этот рекурсивный запрос cte?Любые идеи будут оценены.
Вот представление с рекурсивным CTE - оно извлекает все узлы с данным объектом:
CREATE VIEW adams_test_view AS
WITH eq_mi_cte(miId, eqId, miName, miCode) AS
(SELECT ent.id, ent.id, ent.name, ent.code
FROM entity ent
UNION ALL
SELECT e.id, eq_mi_cte.eqid, e.name, e.code
FROM entity e
INNER JOIN eq_mi_cte ON e.pid = eq_mi_cte.miid)
SELECT * FROM eq_mi_cte
Запрос в представлении с параметром, кажется, запрашиваетвесь вид затем фильтруем его, который никогда не заканчивается, так как дерево слишком большое - мы получаем максимальную ошибку рекурсии:
DECLARE @TopLevelEnt int
SET @TopLevelEnt = 187317;
select * from adams_test_view
WHERE eqId = @TopLevelEnt
Вот план (мои извинения за имена индексов):
|--Filter(WHERE:([Recr1009]=[@TopLevelEnt]))
|--Index Spool(WITH STACK)
|--Concatenation
|--Compute Scalar(DEFINE:([Expr1012]=(0)))
| |--Index Scan(OBJECT:([local_dbname].[dbo].[Entity].[EntityParentId] AS [ent]))
|--Assert(WHERE:(CASE WHEN [Expr1014]>(100) THEN (0) ELSE NULL END))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1014], [Recr1004], [Recr1005], [Recr1006], [Recr1007]))
|--Compute Scalar(DEFINE:([Expr1014]=[Expr1013]+(1)))
| |--Table Spool(WITH STACK)
|--Index Seek(OBJECT:([local_dbname].[dbo].[Entity].[EntityParentId] AS [e]), SEEK:([e].[PId]=[Recr1004]) ORDERED FORWARD)
Теперь, когда я делаю тот же запрос, используя жестко закодированное значение, он возвращает штраф:
запрос:
SELECT * FROM adams_test_view
WHERE eqId = 187317
план:
|--Index Spool(WITH STACK)
|--Concatenation
|--Compute Scalar(DEFINE:([Expr1012]=(0)))
| |--Clustered Index Seek(OBJECT:([local_dbname].[dbo].[Entity].[PK__Entity__2E1BDC42] AS [ent]), SEEK:([ent].[Id]=(187317)) ORDERED FORWARD)
|--Assert(WHERE:(CASE WHEN [Expr1014]>(100) THEN (0) ELSE NULL END))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1014], [Recr1004], [Recr1005], [Recr1006], [Recr1007]))
|--Compute Scalar(DEFINE:([Expr1014]=[Expr1013]+(1)))
| |--Table Spool(WITH STACK)
|--Index Seek(OBJECT:([local_dbname].[dbo].[Entity].[EntityParentId] AS [e]), SEEK:([e].[PId]=[Recr1004]) ORDERED FORWARD)
Я пытался сделатьреорганизовать сущность pk и запустить sp_updatestats
, но без разницы.
Также пытался добавить оптимизацию для подсказки, но, похоже, не поднимал ее, например.
DECLARE @TopLevelEnt int
SET @TopLevelEnt = 187317;
select * from adams_test_view
WHERE eqId = @TopLevelEnt
OPTION (OPTIMIZE FOR (@TopLevelEnt = 187317))
Я выполняю это в базе данных SQL Server 2005 Express из SQL Server Management Studio Express 2008 R2
. Любые подсказки или хакерские сообщения приветствуются.