Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Wpływ rozszerzonego zdarzenia query_post_execution_showplan w programie SQL Server 2012

Jednym z najtrudniejszych wyzwań w programie SQL Server jest rozwiązywanie problemów z wrażliwością parametrów lub szacowaniem kardynalności, które powodują pogorszenie wydajności obciążenia. Ogólnie rzecz biorąc, musisz mieć rzeczywisty plan wykonania z uruchomionej instrukcji, aby móc określić przyczynę obniżenia wydajności. W programie SQL Server 2012 zdarzenie rozszerzone query_post_execution_showplan umożliwia przechwytywanie rzeczywistego planu wykonania instrukcji. Jednak, jakkolwiek przydatne, jak się to wydaje, to zdarzenie nie jest czymś, co może być użyte bez znaczącego wpływu na wydajność pracy na serwerze.

W moim artykule Pomiar „narzutu obserwatora” śledzenia SQL względem zdarzeń rozszerzonych przedstawiłem porównanie wpływu śledzenia SQL na wydajność z identyczną konfiguracją przy użyciu zdarzeń rozszerzonych w programie SQL Server 2012. Przeprowadziłem również wiele testów zdarzenia query_post_execution_showplan w SQL Server 2012. Zdarzenie to zostało po raz pierwszy wprowadzone w SQL Server 2012 CTP1, kiedy wiele zdarzeń śledzenia zostało przeniesionych do zdarzeń rozszerzonych, aby zapewnić parzystość ze śledzeniem SQL. W tamtym czasie wydarzenie miało tylko podzbiór kolumn, które zostały uwzględnione w ostatecznym RTM SQL Server 2012.

Podczas CTP1 przesłałem element Connect z żądaniem utworzenia akcji umożliwiającej zebranie rzeczywistego planu wykonania ze zdarzeniami w SQL Server 2012. Celem było umożliwienie wykorzystania zdarzeń module_end lub sql_statement_completed do określenia, kiedy procedura została wykonana. lub oświadczenie przekracza swój normalny czas trwania. Na przykład w scenariuszu wrażliwości parametrów, w którym dla normalnych wartości parametrów generowany jest mniej idealny plan, zdarzenie może służyć do zebrania rzeczywistego planu wykonania dla tej instrukcji za pomocą akcji. W odpowiedzi zespół SQL Server dodał kolumny duration i cpu_time do zdarzenia query_post_execution_showplan, aby umożliwić definicjom predykatów zbieranie tego zdarzenia tylko dla tych scenariuszy.

Niestety nie ma to takich samych korzyści, jakie implementacja jako akcja miałaby na wydajność. W dalszej części tego postu wyjaśnię dlaczego.

Wpływ na wydajność

W czasie, gdy przeprowadzałem testy do mojego poprzedniego artykułu, przetestowałem również obciążenie związane ze zdarzeniem query_post_execution_showplan, głównie dlatego, że byłem naprawdę zainteresowany użyciem go w kilku klienckich systemach produkcyjnych, a zanim to zrobiłem, musiałem zrozumieć, co rodzaj wpływu, jaki wydarzenie miałoby na ich obciążenie pracą. Byłem naprawdę przerażony wynikami, które uzyskałem z moich oryginalnych testów, a po tym, jak Aaron Bertrand sprawdził moje wyniki za pomocą wewnętrznego zestawu testowego SQL Sentry, złożyłem kolejny element Connect zgłaszający problemy z wydajnością, który został następnie zamknięty jako „Według projektu” .

Do testowania wpływu na wydajność użyto dokładnie tego samego obciążenia i konfiguracji odtwarzania rozproszonego z artykułu Pomiar „narzutu obserwatora” w artykule SQL Trace vs. Extended Events. Jedyna różnica w wynikach testów przedstawionych w tym artykule polega na tym, że w środowisku VM zastosowano nowszy, mocniejszy system hosta. Użyte maszyny wirtualne były dokładnie takie same, bez zmian w ich konfiguracji i zostały po prostu skopiowane do nowego systemu, dlatego podstawowe obciążenie było w stanie wykonać powtórkę szybciej przy wyższej średniej żądań wsadowych na sekundę. Wyniki linii bazowej zostały przechwycone przy użyciu standardowej instalacji SQL Server 2012 z domyślną sesją zdarzenia system_health uruchomioną na serwerze.

Dla porównania wpływu na wydajność query_post_execution_showplan zdarzenie, użyto następującej definicji sesji zdarzenia.

CREATE EVENT SESSION [query_post_execution_showplan Overhead]
ON SERVER
ADD EVENT sqlserver.query_post_execution_showplan(
WHERE ([duration]=(5000000)));
GO

Ta sesja w rzeczywistości nie zbiera danych o zdarzeniach przy użyciu celu i używa predykatu dla czasu trwania zdarzenia, który wynosi 5000000 mikrosekund, czyli pięć sekund. W przypadku obciążenia związanego z odtwarzaniem żadna instrukcja nie trwa dokładnie pięć sekund, więc zdarzenie query_post_execution_showplan nigdy nie jest faktycznie uruchamiane na serwerze, a wszelkie pogorszenie wydajności jest ściśle wynikiem gromadzenia danych o zdarzeniach, a następnie oceny predykatu. Wyniki testów przedstawiono w tabeli 1 i przedstawiono na wykresie 2.


Tabela 1 – obciążenie zdarzenia query_post_execution


Wykres 2 – obciążenie zdarzenia query_post_execution

W tej rundzie testów wydajność obciążenia spada o około 30% po prostu przez włączenie tego zdarzenia w sesji zdarzeń, mimo że nie zostanie ono uruchomione dla żadnego ze zdarzeń odtwarzanych na serwerze. Ogólna degradacja będzie zależeć od rzeczywistego obciążenia serwera i należy zauważyć, że ta seria testów odzwierciedla bardziej najgorszy scenariusz, ponieważ funkcja Distributed Replay została uruchomiona w trybie obciążenia, a użycie procesora na serwerze SQL Server było ustalone średnio 94% podczas testów.

Zrozumienie wpływu na wydajność

Powód, dla którego to zdarzenie nakłada tak znaczny narzut na wydajność, można wyjaśnić na podstawie cyklu życia zdarzenia w zdarzeniach rozszerzonych. Gdy podczas wykonywania napotkany zostanie punkt krytyczny w kodzie programu SQL Server skojarzonego ze zdarzeniem, kod wykonuje bardzo szybkie sprawdzenie typu Boolean, aby określić, czy zdarzenie jest włączone w dowolnej aktywnej sesji zdarzenia na serwerze. Jeśli zdarzenie jest włączone dla aktywnej sesji zdarzenia, gromadzone są wszystkie kolumny danych powiązane ze zdarzeniem, w tym wszystkie kolumny, które można dostosować, które zostały włączone. W tym momencie zdarzenie ocenia wszelkie predykaty dla aktywnych sesji zdarzeń, które zbierają zdarzenie, aby określić, czy zdarzenie faktycznie zostanie uruchomione w całości.

W przypadku zdarzenia query_post_exection_showplan cały wpływ na wydajność wynika z obciążenia związanego z gromadzeniem danych. Nawet w przypadku, gdy istnieje predykat o czasie trwania równym pięciu sekundom, wystarczy włączyć zdarzenie w sesji zdarzenia, musi zebrać XML Showplan dla każdej instrukcji, która jest wykonywana na serwerze, aby móc ocenić predykat a następnie ustalić, że zdarzenie nie zostanie uruchomione. Z tego powodu należy unikać zdarzenia query_post_execution_showplan w przypadku obciążeń produkcyjnych. W przypadku obciążenia testowego powtórki zdarzenie musiało zostać ocenione około 440 000 razy, mimo że w rzeczywistości nie jest uruchamiane dla testowanej sesji obciążenia i zdarzenia, ponieważ żadne ze zdarzeń powtórki nie trwa dokładnie pięć sekund. Informacje o liczbie zdarzeń zostały zebrane przez dodanie celu event_counter do sesji zdarzenia i usunięcie predykatu czasu trwania, a następnie ponowne przetestowanie obciążenia odtwarzania z następującą definicją sesji.

CREATE EVENT SESSION [query_post_execution_showplan Overhead] 
ON SERVER
ADD EVENT sqlserver.query_post_execution_showplan
ADD TARGET package0.event_counter;
GO

Porównanie z szybko strzelającymi zdarzeniami

Aby zapewnić punkt odniesienia dla tego wpływu na wydajność, możemy spojrzeć na obciążenie związane z włączaniem zestawu często wykonywanych zdarzeń na serwerze i wykonywaniem tego samego obciążenia związanego z odtwarzaniem. Dwa z najczęściej wykonywanych zdarzeń w programie SQL Server to zdarzenia lock_acquired i lock_released. Aby porównać obciążenie tych dwóch zdarzeń, można zastosować następującą sesję zdarzeń, która zbiera zdarzenia bez predykatu, dzięki czemu każde wykonanie jest gromadzone i zlicza, jak często są uruchamiane przy użyciu celu event_counter.

CREATE EVENT SESSION [locking Overhead] 
ON SERVER
ADD EVENT sqlserver.lock_acquired,
ADD EVENT sqlserver.lock_released
ADD TARGET package0.event_counter;
GO

W przypadku naszego obciążenia związanego z odtwarzaniem te dwa zdarzenia uruchamiają się około 111 180 000 razy. Narzut związany z gromadzeniem tych zdarzeń można zobaczyć w tabeli 3 i wykresie 4.


Tabela 3 – Porównanie blokowania


Wykres 4 – Porównanie ogólnych zdarzeń blokowania

Jak widać na podstawie danych, wpływ tych zdarzeń na wydajność jest znacznie niższy niż w przypadku query_post_execution_showplan, mimo że definicja sesji zdarzenia blokującego została skonfigurowana tak, aby umożliwić uruchamianie wszystkich zdarzeń na serwerze, całkowity koszt wyniósł poniżej 1% . Należy pamiętać, że sesja zdarzenia blokującego oszacowała równowartość 500 razy większej liczby zdarzeń, aw tym przypadku wszystkie zdarzenia faktycznie musiały zostać uruchomione w sesji zdarzenia, w której zdarzenie query_post_execution_showplan nie musiało faktycznie zostać uruchomione po ocenie.

Podsumowanie

Chociaż zdarzenie query_post_execution_showplan zapewnia możliwość zebrania rzeczywistego planu zapytania dla instrukcji, która jest wykonywana, wpływ na wydajność zbierania danych tylko w celu oceny zdarzenia sprawia, że ​​jest to coś, co nie jest opłacalne do użytku produkcyjnego. Jako minimum należy wziąć pod uwagę narzut, zanim kiedykolwiek użyjesz tego zdarzenia przeciwko obciążeniu produkcyjnemu. Nawet opis zdarzenia dostarczony przez firmę Microsoft potwierdza, że ​​zdarzenie może mieć znaczący wpływ na wydajność (moje wyróżnienie):

Występuje po wykonaniu instrukcji SQL. To zdarzenie zwraca reprezentację XML rzeczywistego planu zapytania. Korzystanie z tego zdarzenia może wiązać się ze znacznym obciążeniem wydajnością, więc powinno być używane tylko podczas rozwiązywania lub monitorowania określonych problemów przez krótki czas.

Opis zdarzenia można znaleźć w kolumnie opisu widoku katalogu sys.dm_xe_objects lub w interfejsie użytkownika nowej sesji, jak pokazano na rysunku 5 (moje wyróżnienie):


Rysunek 5 – Opis zdarzenia z interfejsu użytkownika nowej sesji

Zalecam przetestowanie wydajności każdego zdarzenia z tym ostrzeżeniem w opisie przed faktycznym użyciem go w środowisku produkcyjnym.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Uzyskaj 1 górny wiersz z każdej grupy

  2. Wydajność serwera SQL — testowanie w chmurze

  3. Wyeliminuj i zmniejsz nakładające się zakresy dat

  4. Jak dodać AM/PM do wartości czasu w SQL Server (T-SQL)

  5. Konfigurowanie lokalnej bazy danych SQL Server