Sql server 内部带有递归CTE的极慢表值函数
我创建了一个TVF,它返回一个表,其中包含递归CTE中的父记录。 这非常有效,结果可以直接获得。现在我想获得子记录(它们的FK与当前记录的PK相同)。 问题是,对于给定的id,需要1:10分钟才能获得22个子记录。 为什么这比另一个TVF查找父记录的速度慢? 这是ITVF:Sql server 内部带有递归CTE的极慢表值函数,sql-server,sql-server-2005,performance,common-table-expression,user-defined-functions,Sql Server,Sql Server 2005,Performance,Common Table Expression,User Defined Functions,我创建了一个TVF,它返回一个表,其中包含递归CTE中的父记录。 这非常有效,结果可以直接获得。现在我想获得子记录(它们的FK与当前记录的PK相同)。 问题是,对于给定的id,需要1:10分钟才能获得22个子记录。 为什么这比另一个TVF查找父记录的速度慢? 这是ITVF: CREATE FUNCTION [dbo].[_nextClaimsByIdData] ( @idData INT ) RETURNS TABLE AS RETURN( WITH NextClaims
CREATE FUNCTION [dbo].[_nextClaimsByIdData] (
@idData INT
)
RETURNS TABLE AS
RETURN(
WITH NextClaims
AS(
SELECT 1 AS relationLevel, child.*
FROM tabData child
WHERE child.fiData = @idData
UNION ALL
SELECT relationLevel+1, parent.*
FROM NextClaims nextOne
INNER JOIN tabData parent ON parent.fiData = nextOne.idData
)
SELECT TOP 100 PERCENT * FROM NextClaims order by relationLevel
)
这就是关系:
以及以下示例性查询的(正确)结果:
select relationLevel,idData,fiData from dbo._nextClaimsByIdData(30755592);
rl idData fiData
1 30073279 30755592
2 30765260 30073279
3 31942491 30765260
4 30895945 31942491
5 48045119 30895945
6 48342321 48045119
7 48342320 48342321
8 48308966 48342320
9 48308965 48308966
10 47044261 48308965
11 47044260 47044261
12 47253273 47044260
13 47253272 47253273
14 47279292 47253272
15 47279293 47279292
15 47494589 47279292
16 47494588 47494589
17 46051999 47494588
18 46373053 46051999
19 46083426 46373053
20 46099567 46083426
21 46600314 46099567
22 46595167 46600314
性能丢失的原因可能是,在我的第一个TVF(上面链接)中,我正在寻找主键,而在这个TVF中,我正在寻找(自参考)外键?如果是,如何优化表架构以加速查询
更新:我发现造成此性能问题的原因是fiData(表主键上的foreignkey列)上没有索引。创建和重新组织后,结果立即出现
谢谢。如fiData列上所述索引解决了性能问题如fiData列上所述索引解决了性能问题不知道为什么会变慢
从下一个列表中选择前100%*按关系级别排序
确实很臭,应该用从中选择*下一个目标
。如果要订购,必须通过调用代码完成。执行计划是什么样子的?我想在这个函数中封装顺序(及其复杂性),这样调用方就不必知道内部顺序。但更重要的是,这并不是失去表现的原因。我将在星期一看;)@蒂姆-它发臭的原因是它根本不起作用。它将得到优化。要查看此内容,请尝试将其更改为“按关系级别描述排序”@timschmelter-尝试对视图应用排序肯定是代码味道。一个视图应该像一个表一样表示一组无序的行。此外,即使应用排序,也不能保证输出顺序。也就是说,“根据关系模型,许多人没有意识到这一点,对表表达式的查询不能保证表示顺序,除非最外层的查询有一个presentation ORDER BY子句。表示顺序只在直接级别得到保证,而在代码的外部级别则没有保证。”@Tim Schmelter-示例中的Order By仅由TOP命令用于确定要返回的行。它不是用来规定输出顺序的,这正是伊兹克·本·甘在我提供的文章中抱怨的混乱。不知道为什么它会变慢。SELECT TOP 100%*FROM NextClaims order by relationLevel
确实很臭,应该用SELECT*FROM NextClaims
来代替。如果要订购,必须通过调用代码完成。执行计划是什么样子的?我想在这个函数中封装顺序(及其复杂性),这样调用方就不必知道内部顺序。但更重要的是,这并不是失去表现的原因。我将在星期一看;)@蒂姆-它发臭的原因是它根本不起作用。它将得到优化。要查看此内容,请尝试将其更改为“按关系级别描述排序”@timschmelter-尝试对视图应用排序肯定是代码味道。一个视图应该像一个表一样表示一组无序的行。此外,即使应用排序,也不能保证输出顺序。也就是说,“根据关系模型,许多人没有意识到这一点,对表表达式的查询不能保证表示顺序,除非最外层的查询有一个presentation ORDER BY子句。表示顺序只在直接级别得到保证,而在代码的外部级别则没有保证。”@Tim Schmelter-示例中的Order By仅由TOP命令用于确定要返回的行。它不用于规定输出顺序,这是伊兹克·本·甘在我提供的文章中抱怨的混乱。