2009-08-07 9 views
7

Przepisuję niektóre stare procedury składowane i natknąłem się na nieoczekiwany problem z wydajnością podczas korzystania z funkcji zamiast kodu wbudowanego.Dlaczego prosta funkcja UDF T-SQL sprawia, że ​​wykonanie kodu jest trzykrotnie wolniejsze

Funkcja ta jest bardzo prosty sposób następujący:

ALTER FUNCTION [dbo].[GetDateDifferenceInDays] 
(  
@first_date SMALLDATETIME, 
@second_date SMALLDATETIME 
) 
RETURNS INT 
AS 
BEGIN 

RETURN ABS(DATEDIFF(DAY, @first_date, @second_date)) 

END 

Więc mam dwóch identycznych zapytań, ale używa funkcji, a drugi robi obliczenia w zapytaniu samego:

ABS(DATEDIFF(DAY, [mytable].first_date, [mytable].second_date)) 

Teraz zapytanie z wbudowanym kodem działa 3 razy szybciej niż przy użyciu tej funkcji.

Odpowiedz

14

Co to jest skalarny UDF (przyjmuje 0 do n parametrów i zwraca wartość skalarną). Takie UDF zwykle powodują operację kwerendy po wierszu, chyba że wywołane z parametrami stałymi, z dokładnie taką degradacją wydajności, jakiej doświadczasz w zapytaniu.

Szczegółowe informacje na temat pułapek korzystania z funkcji UDF można znaleźć w następujących szczegółach: here, here i here.

+0

Dziękujemy za publikację. Twój ostatni link to dobra empiryczna analiza tego problemu, ale nie wyjaśnia, dlaczego tak się dzieje. –

+1

@nagul - Twój pierwszy link jest zły. Wygląda na to, że SQLMag zmienił ich adres URL. Czy jest szansa, że ​​to ten artykuł? http://sqlmag.com/user-defined-function-udf/udfs-endanger-performance – EBarr

5

W zależności od kontekstu użycia optymalizator zapytań może analizować kod wbudowany i opracowywać świetny plan kwerendy z wykorzystaniem indeksu, a nie "wstawiać funkcji" w celu przeprowadzenia podobnie szczegółowej analizy, a zatem kończy się z gorszym planem zapytania, gdy funkcja jest zaangażowana. Przyjrzyj się dwóm planom zapytań obok siebie i powinieneś być w stanie łatwo potwierdzić (lub obalić) tę hipotezę!

+0

Dzięki za wysyłkę. Przeanalizowałem dwa plany wykonania i są one identyczne, z wyjątkiem tego, że ten, który nie używa skalarnych UDF, ma "równoległość" przed wykonaniem w zagnieżdżonych pętlach (3 wystąpienia). Wiem, że paralelizm poprawia czas wykonania, ponieważ wykorzystuje wiele procesorów; ale przypuszczam, że to wszystko spowodowane jest brakiem równoległości w planie wykonania? –

13

Nie używaj powolnego skalarnego UDF, użyj szybkiego wbudowanego. Przykłady tutaj:

Reuse Your Code with Table-Valued UDFs

Calculating third Wednesday of the month with inline UDFs

Many nested inline UDFs are very fast

Pytanie jest bardzo powszechne: to zostało zadane i odpowiedzi setki razy wcześniej, jako taka ma kilka puszkach odpowiedzi.

+1

Osoba, która potwierdziła wniosek, podaj przyczynę. –

+1

@Alex: Twój post został również oznaczony jako spam, więc zgaduję, że ktoś (nie ja!) Myśli, że spamujesz linki do swojego bloga, zamiast odpowiadać na pytanie. – RichieHindle

+2

Jeśli linki odpowiadają na pytanie, nie ma znaczenia, czy pochodzą z bloga danego plakatu. Niech dostanie trochę soku Google. To nie tak, że sprzedaje subskrypcje czasopism. To dobry blog; Domyślam się, że przywódca nawet na to nie spojrzał. –

Powiązane problemy