Mam dwa prawie identyczne zapytania uruchomione w tej samej instancji SQL Server 2005:
- Pierwszym z nich jest oryginalne
SELECT
zapytanie wygenerowane przez LINQ (wiem, wiem ... nie jestem programistą aplikacji, tylko DBA :). - Drugi jest dokładnie taki sam jak pierwszy, dodany
OPTION (RECOMPILE)
na końcu.
Nic innego się nie zmieniło.
Pierwszy trwa 55 sekund za każdym razem.
Drugi trwa 2 sekundy.
Oba zestawy wyników są identyczne.
Dlaczego ta wskazówka miałaby generować tak dramatyczny wzrost wydajności?
Wpis Books Online RECOMPILE
nie zawiera zbyt szczegółowego wyjaśnienia:
Nakazuje aparatowi bazy danych SQL Server odrzucić plan wygenerowany dla zapytania po jego wykonaniu, co zmusza optymalizator kwerendy do ponownej kompilacji planu kwerendy przy następnym wykonaniu tego samego zapytania. Bez określania parametru RECOMPILE aparat bazy danych buforuje plany zapytań i wykorzystuje je ponownie. Podczas kompilowania planów zapytań podpowiedź RECOMPILE wykorzystuje bieżące wartości dowolnych zmiennych lokalnych w zapytaniu, a jeśli zapytanie znajduje się w procedurze składowanej, bieżące wartości są przekazywane do dowolnych parametrów.
RECOMPILE jest użyteczną alternatywą dla tworzenia procedury składowanej, która wykorzystuje klauzulę WITH RECOMPILE, gdy tylko podzbiór zapytań wewnątrz procedury przechowywanej, zamiast całej procedury przechowywanej, musi zostać ponownie skompilowany. Aby uzyskać więcej informacji, zobacz Ponowna kompilacja przechowywanych procedur. RECOMPILE jest również przydatny podczas tworzenia przewodników po planach. Aby uzyskać więcej informacji, zobacz Optymalizowanie zapytań we wdrożonych aplikacjach za pomocą Przewodników po planach.
Ponieważ moje zapytanie zawiera wiele zmiennych lokalnych, domyślam się, że SQL Server jest w stanie (poważnie) zoptymalizować je, kiedy korzystam ze OPTION (RECOMPILE)
wskazówki dotyczącej zapytania.
Gdziekolwiek spojrzę, ludzie mówią, że OPTION (RECOMPILE)
należy tego unikać. Wyjaśnienie tego jest na ogół takie, że użycie tej wskazówki SQL Server nie jest w stanie ponownie użyć tego planu egzekucji i dlatego musi tracić czas na jego rekompilację za każdym razem.
(Ale) Biorąc pod uwagę gigantyczną przewagę wydajności, jestem skłonny sądzić, że skorzystanie z tej wskazówki zapytania tym razem byłoby dobrą rzeczą.
Czy powinienem tego użyć? Jeśli nie, to czy mogę zmusić SQL Server do korzystania z lepszego planu wykonania bez tej wskazówki i bez zmiany aplikacji?