Zasugerowano mi, że użycie instrukcji IF w partiach t-SQL jest szkodliwe dla wydajności. Próbuję znaleźć jakieś potwierdzenie lub potwierdzić to twierdzenie. Używam SQL Server 2005 i 2008.
Twierdzenie jest następujące:
IF @parameter = 0
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
SQL Server nie może ponownie użyć wygenerowanego planu wykonania, ponieważ następne wykonanie może wymagać innej gałęzi. Oznacza to, że SQL Server całkowicie wyeliminuje jedną gałąź z planu wykonania na podstawie tego, że dla bieżącego wykonania może już określić, która gałąź jest potrzebna. Czy to naprawdę prawda?
Ponadto, co dzieje się w tym przypadku:
IF EXISTS (SELECT ....)
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
gdzie nie można z góry ustalić, który oddział zostanie wykonany?
sql-server
sql-server-2008
sql-server-2005
query-performance
AnthonyWJones
źródło
źródło
Odpowiedzi:
SQL Server optymalizuje proces kompilacji planu zapytań dla procedury składowanej, ignorując gałęzie warunkowe wewnątrz procedury składowanej. Plan zostanie wygenerowany na podstawie parametrów użytych do pierwszego wykonania, spowoduje to problemy, jeśli parametry będą różne dla gałęzi.
Umieściłbym SQL dla każdej gałęzi we własnej procedurze składowanej, aby wygenerowany plan był oparty na faktycznym użyciu parametrów dla tej gałęzi.
źródło
Jedynym skrótem będzie
IF 1 = 1
Zarówno @parameter, jak i EXISTS nadal wymagają przetwarzania dla „przypadku ogólnego” (
@parameter = 42
powiedzmy)Mówiąc, że ... co mówi rzeczywisty plan wykonania, a także profil rejestrujący zdarzenia rekompilacji? (Nie lubię szacunkowych planów według odpowiedzi Jao)
źródło
Spróbuj wyświetlić szacunkowy plan wykonania, a nie rzeczywisty. Zobaczysz, że pierwszy zawiera
COND
operator.Ten operator został również uwzględniony w buforowanym planie wykonania. W twoim przykładzie szacowany plan wykluczenia będzie zawierał jednego operatora COND i 2 gałęzie SELECT, a zatem będzie w pełni wielokrotnego użytku. Ponieważ podczas wykonywania partii SQL Server ocenia nie tylko instrukcje DML, ale także wszystkie inne, uzyskując je z planu.
Wewnętrzny plan wykonania jest strukturą podobną do drzewa wyrażeń.
źródło
Plany zostaną utworzone na podstawie przekazanych parametrów, więc w rzeczywistości powiedziałbym, że nie - posiadanie logiki warunkowej, która normalnie opiera się na parametrach, nie szkodzi wydajności.
Otrzymasz wiele planów, zakładając, że parametry powodują dostateczną wariancję, aby optymalizator zapytań mógł to zauważyć.
Możesz zobaczyć, które poprzez włączenie planu wykonania, uruchamianie skryptów - zauważ różnice w planie. Kiedy uruchomisz procedury (zakładam, że tutaj są procedury przechowywane), zauważysz, że pierwsze użycie jest generalnie szybsze, drugie trafienie wykorzystuje zapisany plan. Zmień parametry i powtórz, a następnie uruchom oryginalne parametry - teoretycznie plan nadal będzie przechowywany w pamięci podręcznej, ale zależy to od użycia serwera (tiki pamięci podręcznej - nie zostają na zawsze ...) itp.
źródło
Być może został poprawiony w 2005 i 2008 r., Ale użycie warunków warunkowych w 2000 r. Byłoby prawdopodobnie gorsze niż opisujesz, skompilowałoby plan, aby najlepiej obsłużyć pierwszy przebieg procedury, a następnie wykorzystałby ten plan do wykonania procedury, nawet gdy warunki zmienione. Z mojego doświadczenia wynika, że zapytania działające w ciągu kilku minut działały w ciągu kilku godzin. Chociaż korzystam teraz z 2008 r. I korzystałem z 2005 r., Nie mogę komentować, jak działają tam napisane kody, ponieważ już ich nie używam.
źródło