Query Store zmienił sposób, w jaki diagnozujemy problemy wydajnościowe w SQL Server. Po latach zgadywania i ręcznego zbierania danych otrzymaliśmy wreszcie wbudowane narzędzie, które pozwala analizować historię zapytań, zmiany planów wykonania i regresje wydajności w sposób uporządkowany oraz trwały.

- Query Store przechowuje historię zapytań, planów wykonania i metryk wydajności bezpośrednio w bazie danych
- Umożliwia identyfikację regresji wydajności i porównanie planów przed oraz po zmianach
- Force Plan to potężna funkcja, ale wymaga świadomego stosowania
- Prawidłowa konfiguracja retencji i trybu przechwytywania decyduje o użyteczności narzędzia
Geneza Query Store
Przez lata administratorzy SQL Server musieli polegać na kombinacji narzędzi i skryptów, żeby zrozumieć, co dzieje się z wydajnością zapytań. Zbieraliśmy dane z DMV, konfigurowaliśmy trace'y, pisaliśmy własne rozwiązania do archiwizacji planów wykonania. Problem polegał na tym, że DMV pokazują tylko bieżący stan, a po restarcie serwera większość informacji znikała bezpowrotnie.
Microsoft wprowadził Query Store w SQL Server 2016, odpowiadając na jedno z najczęstszych wyzwań DBA: jak udowodnić, że zapytanie działało szybciej tydzień temu i co się od tamtej pory zmieniło? To nie było narzędzie wymyślone w laboratorium; powstało z realnych potrzeb zgłaszanych przez społeczność administratorów.
Architektura i mechanizm działania
Query Store działa na poziomie pojedynczej bazy danych, co oznacza, że musisz go włączyć osobno dla każdej bazy, którą chcesz monitorować. Dane są przechowywane w ukrytych tabelach systemowych wewnątrz tej samej bazy, co ma istotne konsekwencje praktyczne.
Proces zbierania danych
Gdy zapytanie trafia do silnika SQL Server, Query Store przechwytuje jego tekst i generuje unikalny identyfikator (query_id) oparty na hashu tekstu zapytania. Następnie dla każdego planu wykonania tworzony jest osobny identyfikator (plan_id). Ta separacja jest kluczowa, ponieważ jedno zapytanie może mieć wiele różnych planów wykonania w czasie.
Statystyki wykonania są początkowo gromadzone w pamięci, a następnie okresowo zrzucane na dysk. Domyślny interwał to 15 minut, ale można go dostosować parametrem DATA_FLUSH_INTERVAL_SECONDS. Zbyt częste zapisy obciążają IO, zbyt rzadkie zwiększają ryzyko utraty danych przy awarii.
Agregacja metryk
Query Store nie przechowuje informacji o każdym pojedynczym wykonaniu zapytania. Zamiast tego agreguje statystyki w przedziałach czasowych (domyślnie 60 minut). Dla każdego przedziału zapisywane są wartości minimalne, maksymalne, średnie, odchylenie standardowe oraz suma. Taki model pozwala zachować szczegółowość przy rozsądnym zużyciu miejsca.
Z mojego doświadczenia wynika, że godzinny interwał agregacji to dobry kompromis dla większości środowisk produkcyjnych. Przy intensywnym OLTP możesz rozważyć 30 minut, ale pamiętaj o proporcjonalnie większym wzroście rozmiaru Query Store.
Monitorowane metryki
Query Store zbiera kompleksowy zestaw metryk dla każdego planu wykonania:
- Czas wykonania (elapsed time) oraz czas CPU
- Logiczne odczyty (logical reads) i fizyczne odczyty (physical reads)
- Logiczne zapisy i liczba zwróconych wierszy
- Zużycie pamięci przez operatory (memory grant)
- Liczba wykonań i liczba wykonań zakończonych błędem
- Stopień równoległości (DOP) dla zapytań parallel
Od SQL Server 2017 dodano również statystyki wait, co znacząco zwiększyło wartość diagnostyczną narzędzia. Możesz teraz zobaczyć nie tylko że zapytanie trwało długo, ale także na co konkretnie czekało.
Praktyczne scenariusze wykorzystania
Identyfikacja regresji wydajności
Klasyczny scenariusz: użytkownicy zgłaszają, że raport działa wolniej niż zwykle. Bez Query Store zaczynasz od zera, zbierasz aktualny plan, próbujesz odtworzyć poprzedni stan. Z Query Store otwierasz widok Regressed Queries i natychmiast widzisz zapytania, których wydajność spadła w określonym przedziale czasowym.
Raport pokazuje porównanie metryk między przedziałami, a klikając na konkretne zapytanie, widzisz wszystkie plany, które były dla niego używane. Często okazuje się, że optymalizator wybrał nowy plan po aktualizacji statystyk lub przekroczeniu progu rekompilacji.
Analiza po aktualizacji
Przed wdrożeniem zmiany (upgrade SQL Server, zmiana compatibility level, modyfikacja indeksów) warto mieć baseline wydajności. Query Store automatycznie go dostarcza. Po wdrożeniu porównujesz metryki i szybko identyfikujesz zapytania, które ucierpiały.
Diagnostyka po restarcie serwera
To scenariusz, który wcześniej był koszmarem każdego DBA. Serwer został zrestartowany w nocy, rano użytkownicy zgłaszają problemy. Plan cache jest pusty, DMV pokazują dane od momentu startu. Query Store zachował pełną historię, więc możesz porównać zachowanie zapytań przed i po restarcie.
Force Plan: potężne narzędzie wymagające rozwagi
Funkcja wymuszania planu (Force Plan) pozwala przypiąć konkretny plan wykonania do zapytania. Optymalizator będzie go używał niezależnie od zmian w statystykach czy danych. To niezwykle przydatne, ale też ryzykowne.
Kiedy stosować Force Plan
Force Plan sprawdza się jako rozwiązanie tymczasowe, gdy musisz natychmiast przywrócić wydajność produkcji. Zidentyfikowałeś regresję, wiesz że poprzedni plan był lepszy, wymuszasz go i zyskujesz czas na właściwą analizę przyczyny.
Uzasadnione jest też stosowanie Force Plan dla zapytań o stabilnej charakterystyce, gdzie wiesz, że jeden plan jest optymalny niezależnie od dystrybucji danych. Takie przypadki są jednak rzadsze, niż mogłoby się wydawać.
Pułapki wymuszania planów
Wymuszony plan może stać się nieaktualny. Jeśli usuniesz indeks, na którym opiera się plan, zapytanie zacznie się wysypywać. SQL Server co prawda automatycznie zdejmie wymuszenie w przypadku błędu, ale możesz stracić czas na diagnozowanie problemu, który sam stworzyłeś miesiące wcześniej.
Drugi problem to maskowanie prawdziwej przyczyny. Force Plan leczy objaw, nie chorobę. Jeśli plan zmienił się przez nieaktualne statystyki, brakujący indeks lub parameter sniffing, wymuszenie planu tylko odsuwa w czasie właściwe rozwiązanie.
Konfiguracja w środowisku produkcyjnym
Tryby pracy
Query Store oferuje trzy tryby: OFF (wyłączony), READ_WRITE (pełna funkcjonalność) oraz READ_ONLY (tylko odczyt istniejących danych). Tryb READ_ONLY przydaje się przy problemach z przestrzenią dyskową lub gdy chcesz tymczasowo zatrzymać zbieranie bez utraty historii.
Capture Mode
Parametr QUERY_CAPTURE_MODE kontroluje, które zapytania są przechwytywane:
- ALL: każde zapytanie trafia do Query Store
- AUTO: pomija zapytania jednorazowe i te o minimalnym wpływie na wydajność
- CUSTOM (od SQL 2019): pełna kontrola przez progi wykonań, czasu CPU i innych metryk
- NONE: zatrzymuje przechwytywanie nowych zapytań
Dla większości środowisk produkcyjnych rekomenduję tryb AUTO. Tryb ALL generuje znaczący narzut przy intensywnym ruchu ad hoc i szybko zapełnia dostępne miejsce.
Retencja i rozmiar
Parametr CLEANUP_POLICY określa, jak długo dane są przechowywane (domyślnie 30 dni). MAX_STORAGE_SIZE_MB limituje rozmiar Query Store (domyślnie 100 MB, co jest często niewystarczające). Gdy limit zostanie osiągnięty, Query Store przechodzi w tryb READ_ONLY.
W środowisku produkcyjnym ustawiam zazwyczaj 1-2 GB dla MAX_STORAGE_SIZE_MB i 60-90 dni retencji. Te wartości pozwalają na wygodną analizę trendów bez nadmiernego obciążenia systemu.
Typowe błędy konfiguracyjne
Najczęstszy błąd to włączenie Query Store bez późniejszego wykorzystania. Narzędzie zbiera dane, zajmuje miejsce, ale nikt do niego nie zagląda. Query Store wymaga aktywnej analizy, nie działa jak czarna skrzynka samolotu, którą odczytuje się tylko po katastrofie.
Drugi błąd to zbyt mała retencja lub rozmiar. Gdy użytkownik zgłasza problem porównując wydajność do stanu sprzed dwóch miesięcy, a Twoja retencja wynosi 30 dni, tracisz kluczowe dane diagnostyczne.
Trzeci błąd to nadużywanie Force Plan. Widziałem bazy z dziesiątkami wymuszonych planów, gdzie nikt nie pamiętał, dlaczego zostały zastosowane. Regularna rewizja wymuszonych planów powinna być częścią procedur utrzymaniowych.
Integracja z ekosystemem diagnostycznym
Query Store nie zastępuje innych narzędzi diagnostycznych; uzupełnia je. Efektywna diagnostyka wymaga łączenia informacji z wielu źródeł:
- DMV (sys.dm_exec_query_stats, sys.dm_exec_requests): aktualny stan i bieżące wykonania
- Query Store: historia i analiza trendów
- Wait Statistics: identyfikacja wąskich gardeł systemowych
- Extended Events: szczegółowa diagnostyka konkretnych problemów
Typowy workflow wygląda tak: DMV sygnalizują problem w czasie rzeczywistym, Query Store pokazuje, czy to nowe zjawisko czy regresja, Wait Stats wskazują typ wąskiego gardła, a Extended Events pozwalają zgłębić szczegóły konkretnego przypadku.