Tho*_* D. 2 sql-server optimization functions set-returning-functions
我正在尝试为我的公司优化汇总代码,但遇到了一个非常奇怪的问题。我将许多标量函数转换为 TVF,它们似乎都比原始函数运行得更快,这很棒。但是,在调用它们的查询中,它们最终的运行速度明显慢于原始查询。这是我的更新的基本概述:
SELECT col1, ..., colx,
(CASE WHEN x <= 0 OR y <= 0 OR z <= 0 OR z = x
THEN output
WHEN valX <= 0
THEN output
WHEN minimum.min < 1.0 THEN 1.0
ELSE minimum.min
END) AS Q,
FROM Tbl1...tblx (series of inner joins)
CROSS APPLY dbo.inlinemin(val1, val2) AS minimum
Run Code Online (Sandbox Code Playgroud)
这是原文的基本轮廓:
SELECT col1, ..., colx,
(CASE WHEN x <= 0 OR y <= 0 OR z <= 0 OR z = x
THEN output
WHEN valX <= 0
THEN output
ELSE maximum(minimum(val1,val2),1.0)
END) AS Q,
FROM Tbl1...tblx (series of inner joins)
Run Code Online (Sandbox Code Playgroud)
数字或多或少相同,逻辑也是如此。唯一的区别是我的函数 'inlineMin' 是一个 TVF,而不是原始标量函数的 'maximum' 和 'minimum'。这些函数非常简单,只返回两个传递参数之间的最大值或最小值。甚至执行计划也大致相同。有一次从合并连接到哈希匹配的变化,但是,这种差异的代价很小,无法解释经过时间和 CPU 时间的急剧变化。
当我在汇总查询之外运行函数时,对于大量数据,我的函数比原始函数快。考虑到 TVF 与标量 UDF 的工作方式,这是有道理的。但是,当我在查询中调用它们时,我更新后的版本运行速度大约慢了 6 倍。交叉应用(似乎)不是问题,因为离开交叉应用并简单地使用旧功能
SELECT ...
ELSE maximum(minimum(val1,val2),1.0)
END) AS Q,
FROM Tbl1...tblx (series of inner joins)
CROSS APPLY inlinemin(val1, val2) AS NotUsedHere
Run Code Online (Sandbox Code Playgroud)
与原始代码大致一样有效。只有当我在选择中包含我的函数的输出时,查询才会显着变慢。
据我了解,该函数在交叉应用中被调用并运行,这意味着即使它不在选择中,它也应该计算一个值,那么为什么不将它包含在选择中会更快呢?此外,如果上述内容是错误的,为什么我的函数本身会更快,但在查询中使用时运行速度却明显变慢?
编辑:
这是我写的内联 TVF 来替换原来的
CREATE FUNCTION [dbo].[InlineMin](@val1 FLOAT, @val2 FLOAT)
RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
SELECT minVal =
CASE WHEN @val1 < @val2
THEN @val1
ELSE
ISNULL(@val2,@val1)
END
Run Code Online (Sandbox Code Playgroud)
这是我重写的匿名查询计划:https : //www.brentozar.com/pastetheplan/? id =ryKR_Q0Em
以及原始的匿名查询计划:https ://www.brentozar.com/pastetheplan/?id=SJsS1-A4X
据我了解,该函数在交叉应用中被调用并运行,这意味着即使它不在选择中,它也应该计算一个值,那么为什么不将它包含在选择中会更快呢?
优化器非常擅长删除计算最终结果(顶级投影)中不需要的表达式的子树。当您从选择列表中删除该值时,根本没有完成计算该值所需的工作。
此外,如果上述内容是错误的,为什么我的函数本身会更快,但在查询中使用时运行速度却明显变慢?
这很难从匿名计划中详细评估。然而,删除标量 T-SQL 函数允许优化器考虑并行计划。您可能希望使用OPTION (MAXDOP 1)
查询提示来测试您重写的查询,以查看所选串行计划与原始计划的比较情况。
并行计划并不总是更好(尽管只有在优化器的成本似乎较低时才会选择它们)。您的案例成本相对较低,因此优化器认为不值得探索大量替代方案。在某些情况下,考虑串行和并行计划所花费的时间会对最终计划质量产生反作用。
如果这有点含糊,我深表歉意,但匿名计划确实很难具体说明。在所有条件相同的情况下,内联函数目前将优于标量函数。可悲的是,所有事物很少是平等的。
归档时间: |
|
查看次数: |
240 次 |
最近记录: |