2015-03-23 4 views
0
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, используемая в одной из моих хранимых процедур (у меня около 1 миллиона строк данных). С помощью этой функции требуется около 40 секунд.Производительность скалярной функции SQL Server

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

Скалярных функции производительности кошмар, потому что они в основном запустить RBAR (Row-By-Agonizing-Роу HTTPS://www.simple-talk.com/sql/t-sql-programming/rbar--row-by-agonizing-row/). Вам необходимо переписать другой метод, например. напишите непосредственно в своей процедуре [ideal] или используя функцию таблицы. – gvee

ответ

1

Скалярные функции являются кошмаром производительности, поскольку они в основном работают RBAR (Row-By-Agonizing-Row).

Вам необходимо переписать другой метод, например.

  • записи непосредственно в процедуре [идеальной]
  • Используя функцию табличного значения
+0

Спасибо за ответ. Я преобразовал Scalar-значную функцию в табличную функцию и сделал CROSS APPLY. Это уменьшает время выполнения запроса наполовину. Но все же не так, как прямое применение логики к предложению WHERE. Мы говорим о 40 секундах, 20 секундах и 1 секунде. :) – CH81

Смежные вопросы