Optymalizacja: przenoszenie deklaracji zmiennych na szczyt procedury

15

Pracując nad optymalizacją niektórych procedur przechowywanych, usiadłem z DBA i przeszedłem niektóre procedury przechowywane z wysoką aktywnością blokowania i / lub dużą aktywnością odczytu / zapisu.

Jedną rzeczą, o której wspominał DBA było to, że powinienem zadeklarować wszystkie zmienne (zwłaszcza TABLEte) na górze procedury składowanej, aby uniknąć ponownej kompilacji.

To pierwszy raz o tym słyszałem i szukałem potwierdzenia przed ponownym przejrzeniem wszystkich różnych procedur przechowywanych, które mamy. Nazywał to „późnym przeglądaniem kodu”, a rekompilacja blokowała schemat, który tłumaczy blokowanie.

Czy przeniesienie wszystkich deklaracji zmiennych na szczyt procedury składowanej zmniejsza liczbę ponownych kompilacji?

brad.v
źródło

Odpowiedzi:

18

Nie.

To kiedyś było prawdą dawno temu (i już nie jest, przynajmniej od SQL Server 2000), lub nigdy nie było prawdą, a Twój DBA po prostu pomylił swoją rekomendację z następującą :

Ważne jest zgrupowanie wszystkich instrukcji DDL (takich jak tworzenie indeksów) dla tabel tymczasowych na początku procedury składowanej. Umieszczając te instrukcje DDL razem, można uniknąć niepotrzebnych kompilacji z powodu zmiany schematu.

Można znaleźć inne wyjaśnienie co do przyczyn tego zalecenia na tej stronie .

Jeśli spojrzymy na ten KB firmy Microsoft , zauważymy, że przyczyną ponownej kompilacji procedury składowanej może być jedna z następujących przyczyn (SQL Server 2005+):

  1. Schemat się zmienił.
  2. Statystyki się zmieniły.
  3. Ponownie skompiluj DNR.
  4. Zmieniono opcję zestawu.
  5. Tabela temp. Zmieniona.
  6. Zdalny zestaw wierszy został zmieniony.
  7. Zmieniono przeglądarkę perms.
  8. Zmieniono środowisko powiadomień o zapytaniach.
  9. Zmieniono widok MPI.
  10. Opcje kursora zostały zmienione.
  11. Z opcją ponownej kompilacji.

Zadeklarowanie zmiennej - nawet tabeli (tj. @table_variable) - nie może oczywiście wywołać żadnego z tych zdarzeń, ponieważ zadeklarowanie zmiennej nie jest liczone jako DDL . Zmienna (nawet zmienna tabelowa) jest tymczasowym obiektem używanym wyłącznie do programowania T-SQL. Dlatego zmienne tabelowe nie otrzymują statystyk i niepowiązane transakcjami . Zadeklarowanie zmiennej (tabeli lub nie) nie może spowodować ponownej kompilacji proc.

#temp_tableJednak tworzenie tabeli tymczasowej (tj. ) Lub indeksu to DDL, który wpływa na fizyczną definicję bazy danych. Tabele i indeksy temp są „prawdziwymi” obiektami ze statystykami i kontrolą transakcji, dlatego ich utworzenie może wywołać dowolne ze zdarzeń 1, 2 lub 5 z powyższej listy, a tym samym wywołać rekompilację proc.

Nick Chammas
źródło
3

Nie powinno to robić różnicy ani zmniejszać blokad kompilacji ani powodować mniejszej liczby ponownych kompilacji w celu zadeklarowania zmiennej w połowie stosu lub na górze. Zdarza mi się to robić u góry, aby zapewnić czytelność częściej niż nie.

Aby przejść do części pytania „co myślę o DBA”, jedyną rzeczą, jaką mogę wymyślić (poza tym, że Nick myśli o tym, jak kiedyś coś było), być może mówili o węszeniu parametrów (zobacz Opcja 2 pod tym linkiem na prostej rozmowie)

O blokowaniu -> Jeśli widzisz prawdziwe blokowanie, nie jest to typ rywalizacji o blokadę kompilacji, o której najprawdopodobniej mówi DBA. Chociaż prawdą jest, że są pewne rzeczy, które wpływają na to (na przykład nie tabele kwalifikujące schemat, nie kwalifikujące schematu wywołania procedury składowanej), nie jest to z pewnością przyczyną twoich wysokich odczytów i prawdopodobnie nie przyczyną blokowania. Zdecydowanie powinieneś zrobić wszystko, aby uniknąć blokad kompilacji. Chciałbym jednak dostroić i zoptymalizować resztę kodu procedury składowanej jako ważniejsze zadanie niż martwienie się o to, gdzie znajdują się zmienne. Możesz także przeczytać Jak zidentyfikować i rozwiązać blokady kompilacji, jeśli chcesz sprawdzić, czy nie występują tutaj problemy.

Opublikuj je przed / po przykładach, a zobaczymy, o co chodzi w DBA.

Mike Walsh
źródło