Użycie IF w T-SQL osłabia lub przerywa buforowanie planu wykonania?

20

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?

AnthonyWJones
źródło
1
SQL Server może i ponownie wykorzystuje plan wykonania, ponieważ nie uwzględnia rozgałęzień, tylko instrukcje zawarte w rozgałęzieniach.
MartinC

Odpowiedzi:

10

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.

MartinC
źródło
6

Jedynym skrótem będzie IF 1 = 1

Zarówno @parameter, jak i EXISTS nadal wymagają przetwarzania dla „przypadku ogólnego” ( @parameter = 42powiedzmy)

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)

gbn
źródło
3

Spróbuj wyświetlić szacunkowy plan wykonania, a nie rzeczywisty. Zobaczysz, że pierwszy zawiera CONDoperator.

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ń.

Tom V - Team Monica
źródło
0

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.

Barry King
źródło
0

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
2
2005+ ma rekompilację na poziomie instrukcji, więc nie masz już „jednego planu na sp” przez cały czas
gbn