SQL Server标量函数的性能

时间:2015-03-23 17:38:21

标签: sql-server tsql sql-function

CREATE FUNCTION GETBUSINESSDATEDIFF
(
    @startdate as DATETIME,
    @enddate as DATETIME
)
RETURNS INT
AS
BEGIN
    DECLARE @res int

SET @res = (DATEDIFF(dd, @startdate, @enddate) + 0)
    -(DATEDIFF(wk, @startdate, @enddate) * 2)
    +(CASE WHEN DATEPART(dw, @startdate) = 1 THEN 1 ELSE 0 END)
    -(CASE WHEN DATEPART(dw, @enddate) = 7 THEN 1 ELSE 0 END)

    RETURN @res
END
GO

我在我的一个存储过程中使用了这个SQL Server标量函数(我有大约100万行数据)。使用此功能需要大约40秒才能执行。

AND dbo.GETBUSINESSDATEDIFF(L.Date4, L.Date2) <= 4

但是如果我将逻辑直接移动到我的存储过程而不是调用函数,它会在1秒内返回数据。

AND ((DATEDIFF(dd, L.Date4, @ToUTCDate) + 0)
    -(DATEDIFF(wk, L.Date4, L.Date2) * 2)
    +(CASE WHEN DATEPART(dw, L.Date4) = 1 THEN 1 ELSE 0 END)
    -(CASE WHEN DATEPART(dw, L.Date2) = 7 THEN 1 ELSE 0 END)) <= 4

有关如何改善此事的任何建议吗?

1 个答案:

答案 0 :(得分:2)

标量函数是性能噩梦,因为它们基本上运行 RBAR Row-By-Agonizing-Row)。

您需要使用其他方法重写,例如

  • 直接写入您的程序[理想]
  • 使用表值函数