2009-08-07 25 views
7

我重写一些旧的存储过程,我已经使用功能,而不是内嵌代码时遇到意想不到的性能问题。为什么一个简单的T-SQL UDF功能,使代码执行慢3倍

的功能如下非常简单:

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

回答

14

你有什么是标量UDF(取0到n参数和返回标量值)。这种UDF通常会引起查询的逐行操作,除非使用常量参数进行调用,这与您查询时遇到的那种性能下降完全相同。

请参阅here,herehere以了解使用UDF的性能缺陷的详细说明。

+0

感谢您发表。你的最后一个链接是对这个问题的一个很好的实证分析,但并不能解释为什么会出现这种行为。 – 2009-08-10 11:59:30

+1

@nagul - 你的第一个链接是坏的。看起来像SQLMag改变了他们的URL。这是文章的任何机会吗? http://sqlmag.com/user-defined-function-udf/udfs-endanger-performance – EBarr 2013-09-21 19:17:06

5

根据使用环境,查询优化器可以能够分析内嵌代码,并找出一个伟大的使用索引查询计划,虽然它没有“内联函数”为类似的详细分析等结束在涉及函数时使用低级查询计划。并排查看两个查询计划,并且您应该可以很容易地确认(或反驳)这个假设!

+0

感谢发布。我分析了两个执行计划,它们是相同的,只是不使用标量UDF的执行计划在执行嵌套循环(3次出现)之前具有“并行性”。我知道并行性利用多个处理器来提高执行时间;但我是否应该认为这全部是由于执行计划缺乏并行性? – 2009-08-10 12:12:11

13

不要使用缓慢的标量UDF,使用快速内嵌一个。例如这里:

Reuse Your Code with Table-Valued UDFs

Calculating third Wednesday of the month with inline UDFs

Many nested inline UDFs are very fast

的问题是很常见的:它已经被问和回答过上百次,因此它有几个罐头的答案。

+1

谁downvoted,请提供理由。 – 2009-08-08 23:46:38

+1

@Alex:您的帖子也被标记为垃圾邮件,所以我的猜测是有人(而不是我!)认为您将垃圾链接发送到您的博客而不是回答问题。 – RichieHindle 2009-08-09 14:48:25

+2

如果链接回答这个问题,它们是否来自海报自己的博客并不重要。让他得到一些谷歌果汁。这不像他在出售杂志订阅。这是一个很好的博客;我的猜测是旗手甚至没有看到它。 – 2009-08-09 20:52:29