gpt4 book ai didi

sql-server - 是否可以强制SQL Server使用我想要优化递归cte查询的计划

转载 作者:行者123 更新时间:2023-12-03 01:00:29 24 4
gpt4 key购买 nike

我在一个 View 中使用大树上的递归 cte 进行查询,当使用硬编码数字而不是参数进行查询时效果很好。是否可以强制 SQL Server 使用我想要优化此递归 cte 查询的计划?任何想法将不胜感激。

这是具有递归 CTE 的 View - 它检索给定实体下的所有节点:

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

使用参数对 View 进行查询似乎会查询整个 View ,然后对其进行过滤,但由于树太大而永远不会完成 - 我们得到最大递归错误:

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 Management Studio Express 2008 R2 的 SQL Server 2005 Express 数据库上运行此程序

任何提示或黑客行为将不胜感激。

最佳答案

您看到的是正常的,因为 View 首先返回所有内容,然后查看变量并相应地进行过滤。当它被硬编码时,它会选择另一个计划,因为它从一开始就知道要应用哪个过滤器。

您是否尝试过使用内联表值函数执行相同的操作,并在 cte 的上部选择上使用过滤器?

关于sql-server - 是否可以强制SQL Server使用我想要优化递归cte查询的计划,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6171486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com