如何更改系统范围的默认值MAXRECURSION
?
默认情况下为100,但是我需要将其增加到1000。
我无法使用查询提示,因为我使用的程序会接受我的查询并为我执行查询,但是不幸的是,我无法解决此限制。
但是,我确实对服务器实例具有管理员权限。我在服务器方面进行了摸索,但没有看到与查询选项或递归相关的任何信息。我假设有有是一个某处在那里我可以更新系统范围内的默认。
有任何想法吗?
如何更改系统范围的默认值MAXRECURSION
?
默认情况下为100,但是我需要将其增加到1000。
我无法使用查询提示,因为我使用的程序会接受我的查询并为我执行查询,但是不幸的是,我无法解决此限制。
但是,我确实对服务器实例具有管理员权限。我在服务器方面进行了摸索,但没有看到与查询选项或递归相关的任何信息。我假设有有是一个某处在那里我可以更新系统范围内的默认。
有任何想法吗?
Answers:
如果查询的形状相同,则可以使用一个或多个计划指南来添加所需的maxrecursion提示。
弄清楚它们是有诀窍的。如果您在问题中添加特定的查询详细信息,我们可能会为您解决。通常,您将跟踪实际击中服务器的SQL,或者使用内置过程sys.sp_get_query_template获取参数化形式,然后创建TEMPLATE和/或OBJECT / SQL计划指南。
请参阅文档以获取更多信息:
每当应用程序代码更改以及SQL Server修补或升级时,都需要重新验证计划指南。这应该只是正常测试周期的一部分。
请注意,如果被引导的语句引用了临时表,则使用sys.fn_validate_plan_guide进行计划指南的验证可能会错误地报告失败。看到这个问题:
使用fn_validate_plan_guide进行计划指南验证会产生误报
该计划指南成功和计划指南不成功的探查和扩展事件类也可以用来监测计划指南应用程序。
在实现产品改进建议之前,史蒂夫·卡斯(Steve Kass)的视图和UDF的“允许MAXRECURSION”极限值不为100时, Connect已被淘汰。如果您现在想使用Microsoft,请参阅SQL Server帮助和反馈中的选项。
如果您必须使用某个函数(暗示您的ETL工具的局限性),则可以将其指定OPTION
为多语句表值函数的一部分,例如:
CREATE FUNCTION dbo.udf_MyFunction ( @StartID INT )
RETURNS @tv TABLE
(
id INT
)
AS
BEGIN
WITH Episodes( xlevel, PersonID, EventID, EpisodeID, StartDT, EndDT ) AS (
-- Anchor case - the first EventID for each person.
SELECT 1 AS xlevel, PersonID, EventID, @StartID, StartDT, EndDT
FROM dbo.EventTable
WHERE EventID = @StartID
UNION ALL
SELECT xlevel + 1, et.PersonID, et.EventID, c.EventID + 1, et.StartDT, et.EndDT
FROM Episodes c
INNER JOIN dbo.EventTable et ON c.PersonID = et.PersonID
AND et.EventID = c.EventID + 1
--WHERE c.EventID <= (@StartID + 99)
)
INSERT INTO @tv
SELECT PersonID
FROM Episodes
OPTION ( MAXRECURSION 1000 )
RETURN
END
GO
当您建议使用ETL工具时,将其包装在视图中时,这也对我有用。无法在整个系统范围内进行更改,但是由于递归效率低下,这可能是一件好事。OPTION
如示例所示,您不能在内联表值函数的主体内指定查询提示(使用)。
考虑收到您的情节并将输出存储在关系表中时,更改流程以仅遍历层次结构一次。您可以使用存储的proc来执行此操作,因此不会遇到此限制。
我还认为您的代码中可能存在一个错误:如果您的CTE加入personId并在eventId上递归,则eventId 101会重复出现两次。可能我误解了您的代码,请告诉我您的想法。
高温超导
我从这个话题中得到启发。
这是我为解决问题所做的工作。
CREATE FUNCTION MySchema.udf_MyFunction(@StartID INT)
RETURNS TABLE
AS RETURN
WITH
Episodes(PersonID, EventID, EpisodeID, StartDT, EndDT) AS (
-- Anchor case - the first EventID for each person.
SELECT PersonID, EventID, @StartID, StartDT, EndDT
FROM MySchema.EventTable
WHERE EventID = @StartID
UNION ALL
SELECT
...
WHERE
EventID <= (@StartID + 99)
)
SELECT * FROM Episodes
然后,我像这样调用此函数:
WITH
Episodes AS (
SELECT * FROM MySchema.udf_MyFunction(1)
UNION ALL
SELECT * FROM MySchema.udf_MyFunction(101)
UNION ALL
SELECT * FROM MySchema.udf_MyFunction(201)
-- ...
UNION ALL
SELECT * FROM MySchema.udf_MyFunction(901)
)
SELECT * FROM Episodes
这样,我的CTE逻辑就不必重复了,而且我在性能方面不需要付出任何额外的费用。这样做很麻烦,但我可以接受。
where
省略号后子句防止太多递归从使用功能参数作为约束发生。我想在CTE定义之后应该有一个声明。我将添加。
EventID=1
(和101,201,... 901)为起点(行)调用函数。但是原始查询(如果以MAXRECURSION = 100000000运行)可能永远不会访问带有EventID=101
(和201,..,901)的行。因此,这两个查询(原始查询和您的解决方案)可能返回不同的结果(第一个行中没有101,第二个行中是)!或者,它可以访问101,但步骤100之前,让您的解决方案将包括在结果两次行(再次不同)