Powiem od początku, że moje pytanie / problem, wygląda podobnie do tego poprzedniego, ale ponieważ nie jestem pewien, czy przyczyną lub informacji wyjściowy jest taki sam, postanowiłem odpowiedzieć na moje pytanie z trochę więcej szczegółów.
Poddany problem:
- o dziwnej godzinie (pod koniec dnia roboczego) instancja produkcyjna zaczyna zachowywać się niepoprawnie:
- wysoki procesor dla instancji (w stosunku do wartości wyjściowej ~ 30% wzrósł do około dwukrotnie i wciąż rośnie)
- zwiększona liczba transakcji / sekundę (chociaż obciążenie aplikacji nie zauważyło żadnych zmian)
- zwiększona liczba bezczynnych sesji
- dziwne zdarzenia blokujące między sesjami, które nigdy nie wyświetlały tego zachowania (nawet czytanie niezaangażowanych sesji powodowało blokowanie)
- górne oczekiwania na interwał to brak blokady strony na 1. miejscu, a blokady zajmują 2. miejsce
Wstępne dochodzenie:
- za pomocą sp_whoIsActive widzieliśmy, że zapytanie wykonane przez nasze narzędzie monitorujące decyduje się na bardzo wolne działanie i pobranie dużej ilości procesora, co nie zdarzyło się wcześniej;
- jego poziom izolacji został odczytany jako niezaangażowany;
- przyjrzeliśmy się planowi, który widzieliśmy niepoprawne liczby: StatementEstRows = "3.86846e + 010" z około 150 TB danych szacunkowych do zwrócenia
- podejrzewaliśmy, że przyczyną była funkcja monitorowania zapytań w narzędziu do monitorowania, więc wyłączyliśmy tę funkcję (otworzyliśmy również bilet u naszego dostawcy, aby sprawdzić, czy jest świadomy jakiegokolwiek problemu)
- od pierwszego zdarzenia zdarzyło się to jeszcze kilka razy, za każdym razem, gdy zabijamy sesję, wszystko wraca do normy;
- zdajemy sobie sprawę, że zapytanie jest bardzo podobne do jednego z zapytań używanych przez MS w BOL do monitorowania magazynu zapytań - zapytania, które ostatnio uległy regresji pod względem wydajności (porównanie różnych punktów w czasie)
- uruchamiamy to samo zapytanie ręcznie i widzimy to samo zachowanie (procesor ciągle rośnie, rośnie czas oczekiwania na zatrzask, nieoczekiwane blokady itp.)
Winne zapytanie:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
Ustawienia i informacje:
- SQL Server 2016 SP1 CU4 Enterprise w klastrze Windows Server 2012R2
- Magazyn zapytań włączony i skonfigurowany jako domyślny (bez zmiany ustawień)
- baza danych zaimportowana z instancji SQL 2005 (i nadal na poziomie zgodności 100)
Obserwacja empiryczna:
- ze względu na bardzo zwariowane statystyki, wzięliśmy wszystkie * plan_persist ** obiekty użyte w złym oszacowanym planie (brak rzeczywistego planu, ponieważ zapytanie nigdy się nie zakończyło) i sprawdziliśmy statystyki, niektóre indeksy użyte w planie nie miały żadnych statystyk (DBCC SHOWSTATISTICS nic nie zwrócił, wybierz z sys.stats pokazał NULL funkcja stats_date () dla niektórych indeksów
Szybkie i brudne rozwiązanie:
- ręcznie utwórz brakujące statystyki dotyczące obiektów systemowych związanych ze sklepem zapytań lub
- wymusza uruchomienie zapytania przy użyciu nowego CE (traceflag) - który również utworzy / zaktualizuje niezbędne statystyki lub
- zmień poziom kompatybilności bazy danych na 130 (aby domyślnie używał nowego CE)
Tak więc moim prawdziwym pytaniem byłoby:
Dlaczego zapytanie w magazynie zapytań powoduje problemy z wydajnością w całej instancji? Czy jesteśmy na terytorium błędów w Query Store?
PS: Prześlę kilka plików (ekrany drukowania, statystyki IO i plany) w krótkim czasie.
Pliki dodane do Dropbox .
Plan 1 - początkowy nieprecyzyjny plan produkcji
Plan 2 - aktualny plan, stary CE, w środowisku testowym (to samo zachowanie, te same zwariowane statystyki)
Plan 3 - aktualny plan, nowy CE, w środowisku testowym