我正在重写一些旧的存储过程,并且在使用函数而不是内联代码时遇到了意外的性能问题。
该功能非常简单如下:
ALTER FUNCTION [dbo].[GetDateDifferenceInDays]
(
@first_date SMALLDATETIME,
@second_date SMALLDATETIME
)
RETURNS INT
AS
BEGIN
RETURN ABS(DATEDIFF(DAY, @first_date, @second_date))
END
所以我有两个相同的查询,但是一个使用该函数,另一个在查询中进行计算:
ABS(DATEDIFF(DAY, [mytable].first_date, [mytable].second_date))
现在使用内联代码的查询运行速度比使用该函数的查询快3倍。
答案 0 :(得分:14)
你拥有的是标量UDF(取0到n个参数并返回一个标量值)。这样的UDF通常会导致查询的逐行操作,除非使用常量参数调用,而这与您在查询中遇到的性能降低完全相同。
答案 1 :(得分:13)
不要使用慢速标量UDF,请使用快速内联UDF。这里的例子:
Reuse Your Code with Table-Valued UDFs
Calculating third Wednesday of the month with inline UDFs
Many nested inline UDFs are very fast
这个问题非常普遍:之前已经被问过并回答了数百次,因此它有一些罐头答案。
答案 2 :(得分:5)
根据使用情况,查询优化器可能能够分析内联代码并找出一个很好的索引使用查询计划,而它没有“内联函数”进行类似的详细分析,因此最终得到涉及函数时的劣质查询计划。并排查看两个查询计划,您应该能够很容易地确认(或反驳)这个假设!