我正在重写一些旧的存储过程,并且在使用函数而不是内联代码时遇到了意外的性能问题。

该函数非常简单,如下所示:

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倍。

#1楼 票数:14 已采纳

您拥有的是标量UDF(采用0到n个参数并返回标量值)。 除非使用常量参数调用,否则此类UDF通常会导致查询的逐行操作,从而导致查询性能下降。

有关使用UDF的性能陷阱的详细说明,请参见此处此处此处

#2楼 票数:13

不要使用慢速标量UDF,而要使用快速内联UDF。 这里的例子:

与表值UDF复用代码

使用内联UDF计算该月的第三个星期三

许多嵌套的内联UDF非常快

这个问题非常普遍:它已经被问过数百遍,因此有一些罐头答案。

#3楼 票数:5

根据使用情况的不同,查询优化器可能能够分析内联代码并找出使用索引的出色查询计划,而不会“内联函数”以进行类似的详细分析,因此最终导致查询质量降低计划涉及该功能的时间。 并排查看两个查询计划,您应该能够轻松确认(或反对)这一假设!

  ask by Giuseppe Romagnuolo translate from so

未解决问题?本站智能推荐:

3回复

T-SQL流程设计和执行计划(UDF参数嗅探?)

在SQL Server 2005上,我有一个复杂的多级分配过程,如下所示(伪SQL): 在其中ALLOCS带有直接分配的种子,然后BALANCES(@LVL_NUM)基于ALLOCS的@LVL_NUM (可能是一些直接分配加上上一级的一些IN分配),而ALOCNS(@LVL_NUM)是基于A
7回复

T-SQL用户定义函数重载?

我知道T-SQL不是面向对象的。 我需要编写一组模拟C#中方法重载的函数。 是否在T-SQL中以任何方式支持函数重载? 如果有黑客这样做,建议吗?
2回复

一个远程可以从t-sql中执行查询吗?

首先是原始问题: 假设有2个DB:DB1和DB2。 连接到DB1时,是否可以像登录到DB2一样对DB2执行查询? 所以基本上: 我已连接到DB1 从TSQL内部,我以某种方式连接到DB2 我在本地执行查询(并等待) 我关闭连接,然后回到DB1 我将执行其余的
2回复

这个T-SQL代码发生了什么?(连接SELECT语句的结果)

我刚刚开始学习T-SQL,可以使用一些帮助来理解特定代码块中发生的事情。 我在上一个问题中收到的答案中修改了一些代码,这里是有问题的代码: T-SQL代码完全符合我的要求,即根据查询结果生成单个结果,然后将在另一个查询中使用。 但是,我想不出如何SELECT @column_list
1回复

T-Sql函数中的动态openrowset还是可行的替代方案?

我不太确定该如何表达。 这是问题所在: 我有1-n项需要加入其他系统(AS400)才能获取一些数据。 如果我在openrowset之外指定where条件,则openrowset将永远openrowset ,例如: 我的想法是创建一个接受项目编号的函数,并使用动态sql将其注入到op
4回复

使用表参数创建T-SQL函数

我需要用表参数编写函数。 一个例子: 我能怎么做? 谢谢
3回复

T-SQL:可变范围

我试图将SQL查询的结果存储到变量中。查询只是检测列的数据类型,因此返回的结果是单个varchar。 “SET声明”中的任何内容都无法访问它之外的任何变量,反之亦然,因此我坚持如何将此查询的结果存储在varchar变量中,以供存储过程的其他部分访问。
1回复

T-SQL条件IF语句

我有一个看起来像这样的记录集: DocID(主键)| 版本| 名称 4 | 1 | FileNameA 8 | 2 | FileNameA 6 | 1 | FileNameB 3 | 1 | FileNameC 我需要做的是仅显示版本号大于1的唯一文件