W ostatnie dwie środy zorganizowaliśmy dwuczęściową serię seminariów internetowych poświęconych problemom z wrażliwością parametrów:
- Procedury przechowywane, parametry, problemy…
Kimberly L. Tripp i Aaron Bertrand
24 stycznia
Przegapiłeś? Zarejestruj się, aby obejrzeć to teraz! - Wąchanie parametrów za pomocą SentryOne
Aaron Bertrand, Kimberly L. Tripp i Andy Mallon
31 stycznia
Przegapiłeś? Obejrzyj teraz!
Podczas obu webinariów pojawiły się pewne pytania i pomyślałem, że skompiluję je i odpowiem tutaj (niektóre odpowiedzi pochodzi od Andy'ego podczas webinaru).
W przypadku problemu, który ostatnio widzieliśmy, widzimy, że plany są bardzo szybko usuwane z pamięci podręcznej. Nie wykonujemy niczego, co opisujesz (
DBCC FREEPROCCACHE
itp.); czy presja pamięci również może to spowodować?
Tak, ciśnienie pamięci może być czynnikiem (patrz ten post) i wiem, że istnieją pewne badania dotyczące potencjalnych problemów z zarządzaniem pamięcią SQL Server również w tym zakresie.
Od uczestnika:„Nie pytanie, ale komentarz do użytkownika pytający o to, ile razy pamięć podręczna jego planu jest opróżniana. To też mieliśmy i rzeczywiście było to ciśnienie pamięci. naprawiono za pomocą wspomnianej tutaj formuły, a następnie uruchomiliśmy procedurę z tego artykułu co 10 minut (mamy mnóstwo dynamicznego SQL, użytego tylko raz).
Co się stanie, jeśli użyjesz
OR
w klauzuli WHERE zamiastAND
, czy problem będzie się utrzymywał?
Zwykle, jeśli używasz
OR
w tego typu wzorcu za każdym razem otrzymasz wszystkie wiersze, chyba że każdy parametr jest wypełniony wartościami filtrującymi wiersze. Zmienia to semantykę zapytania z „wszystkie te rzeczy muszą być prawdziwe” na „każda z tych rzeczy może być prawdziwa”. Mimo to plan, który jest skompilowany dla pierwszego zestawu parametrów, nadal będzie buforowany i utrwalony dla przyszłych wykonań, niezależnie od tego, czy klauzule używająAND
lubOR
.
Czy to
1=1
? oznaczyć dobre podejście? Czy nie jest lepiej dodać tylko podane parametry, a tym samym uniknąć brzydkiego1=1
?
1 = 1
jest praktycznie ignorowany przez SQL Server, ale pozwala na dodanie wszystkich klauzul warunkowych za pomocąAND
byś nie musiał traktować *pierwszego* w inny sposób. Oto alternatywa:SET @IncludedWhereClauseYet bit = 0; SET @sql = N'SELECT cols FROM dbo.Table'; IF @param1 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 BEGIN SET @sql += N' WHERE '; SET @IncludedWhereClauseYet = 1; END ELSE BEGIN SET @sql += N' AND '; END SET @sql += N' @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 ... END ...
1=1
pozwala na uproszczenie, pozwalając zawsze poprzedzać każdą klauzulę za pomocąAND
. Powyższy kod staje się:SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1'; IF @param1 IS NOT NULL BEGIN SET @sql += N' AND @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN SET @sql += N' AND @param2 = @param2'; ENDByć może możesz użyć innej klauzuli początkowej, aby uniknąć wszystkich warunków, takich jak
WHERE PrimaryKey > 0
lubWHERE PrimaryKey IS NOT NULL
, a następnie każda kolejna klauzula może zaczynać się odAND
. Ale1 = 1
, choć brzydkie, jest nieszkodliwe, a IMHO nie jest mniej brzydkie niż dodanie *prawdziwej*, ale bezsensownej klauzuli, z wyjątkiem tego, że *prawdziwa* klauzula może wpłynąć na plan.Pamiętaj, że kiedy tworzysz kod T-SQL za pomocą T-SQL, musisz pomyśleć o dwóch aspektach „brzydkich” — czasami będziesz rozwiązywać problemy z powyższym kodem, a czasami będziesz rozwiązywać problemy z zapytaniem, które wychodzi z to. Uważaj na poświęcanie jednego dla dobra drugiego.
CO?! Całkowicie przegapiłem to…
WITH RECOMPILE
. Myślałem, że to opróżniło plan, ale zostawiłem to w spokoju tylko dla tej egzekucji… to bardzo ważne, aby wiedzieć!
Tylko upewnij się, że znasz również wady.
Zobacz ten wspaniały post Paula White'a.
Czy
OPTION OPTIMIZE FOR @parametername UNKNOWN
? nie jest już preferowany w nowszych wersjach SQL?
Nie sądzę, aby był lepszy lub gorszy we współczesnych wersjach niż wtedy, gdy został wprowadzony po raz pierwszy w SQL Server 2008. O ile mi wiadomo, nawet po wszystkich zmianach w optymalizatorze i estymatorze kardynalności ten bit nadal zachowuje się w ten sam sposób.
Czy jest jakieś obciążenie serwera, jeśli włączę przechwytywanie statystyk procedur i statystyk zapytań w SentryOne?
Kolekcja statystyk Procedur i zapytań powinna być domyślnie włączona. Każde zbieranie danych wiąże się z pewnymi kosztami, ale SQL Sentry dość ostrożnie podchodzi do tego, jaki koszt ponosi zbieranie.
Wyszukiwanie na RS nie używało go jako predykatu rezydualnego, ale szukało czegoś innego, czego nie mogłem zobaczyć.
Dzięki, powrócę do tego przykładu i osobno napiszę blog o demonstracjach, upewniając się, że zawierają wszelkie istotne szczegóły, które nie były oczywiste z samego diagramu planu.
Czy nie jest prawdą, że dodanie niektórych kolumn potrzebnych jako
INCLUDE
? s faktycznie nie zwiększa efektywności indeksu, ponieważ wyszukiwanie klucza nie zostanie wyeliminowane? Myślę, że procent nie powinien się zmienić, chyba że faktycznie wyeliminujesz wyszukiwanie klucza.
Ściśle tak, to prawda. Pierwotne zapytanie było bardzo złym przykładem, używając
SELECT *
oraz indeks, w którym brakuje beznadziejnej liczby kolumn. Chodziło mi o to, że zakładka Analiza indeksu zachęca zarówno do (a) ulepszenia zapytania, jak i (b) stworzenia okładki indeksu. Wynik ma zachęcić Cię do wykonania jednego lub obu tych elementów — jeśli zmienisz zapytanie, aby potrzebować mniej kolumn, indeks będzie również bliższy objęcia zapytania. Jeśli zamierzasz utworzyć nowy, oddzielny indeks obejmujący, masz również informacje o tym, które kolumny są wymagane do objęcia tego konkretnego zapytania. Technicznie masz rację, dodanie jednej kolumny include, ale nadal wymaga przeszukania 4 innych, nie poprawi wydajności tego konkretnego zapytania i nie poprawi indeksu, ale wskazuje, że „ ponownie się zbliża. Mamy nadzieję, że nie poprzestaniesz na dodaniu jednej kolumny include i zignorujesz resztę. Nie wiemy, kiedy przestaniesz, więc nie wiem, czy istnieje idealne rozwiązanie – na pewno nie chcemy zniechęcać użytkowników, aby ich indeksy były lepiej dopasowane do ich zapytań.
Dlaczego widzimy zapytania używające parametru imienia i parametru nazwiska podsumowanego pod wyrażeniem używającym tylko parametru nazwiska?
AKTUALIZACJA: To jest celowe. Grupowanie w obszarze Pokaż sumy grupuje tę samą procedurę wywołaną ze wszystkimi różnymi kombinacjami parametrów. Możesz więc użyć go najpierw do określenia, które parametry powodują najgorszą wydajność, a następnie zbadać, czy dane są przekrzywione. Na przykład parametr, który prowadzi do wyszukiwania w kolumnie nieindeksowanej, będzie prawdopodobnie dość niezawodnie przeskakiwać do góry i można to zobaczyć w połączeniu z innymi parametrami, które są przekazywane, a także porównywane ze wszystkimi wywołaniami, w których ten parametr był minęło.
Powiedziawszy to wszystko, postaramy się dopracować to zachowanie grupowania, gdy zakończymy zmiany aktualnie wprowadzane dla ekranu Top SQL.
Czy jest jakaś dokumentacja, jak korzystać z przewodnika po planie? Obecnie nie mam pojęcia, jak to zrobić.
To jest coś, o czym chciałem napisać na blogu, ale w międzyczasie Microsoft ma tu kilka tematów (i sprawdź wszystkie powiązane linki na pasku bocznym).
Czy muszę coś włączyć, aby uzyskać wykres historii zapytań?
Nie, powinno to być włączone we wszystkich nowoczesnych wersjach aplikacji klienckiej SentryOne. Jeśli go nie widzisz, spróbuj
Tools > Reset Layout
; jeśli to nie zadziała, skontaktuj się z [email protected].
Czy istnieją przypadki, w których wymuszanie ostatniego znanego dobrego planu przy użyciu magazynu zapytań, gdy regresja planu okaże się złym pomysłem? Czy spowoduje to ukrycie problemów, które można lepiej rozwiązać poprzez zmianę oświadczenia, tak jak pokazałeś?
Wymuszenie planu jest często ostatecznością i zwykle rezerwuję go na wypadek, gdy naprawdę, naprawdę, naprawdę nie możesz naprawić instrukcji (lub zmienić indeksu). Wymuszanie planu zawsze może prowadzić do niewłaściwego zachowania, ponieważ nadal to człowiek dokonuje takiego wyboru, a Ty możesz dokonywać go na podstawie złych informacji. Regresja może być spowodowana zmianą planu, ale jeśli oceniasz to jako regresję, ponieważ czas działania był dłuższy, czy zbadałeś inne możliwe przyczyny? Załóżmy na przykład, że system został ponownie uruchomiony lub nastąpiła awaria i otrzymał nowy plan, ponieważ stary został usunięty, a może w międzyczasie zmieniły się również statystyki, ale teraz zapytanie działa dłużej nie dlatego, że plan jest gorszy, ale raczej dlatego, że bufory były puste. Więc tak, z pewnością nie sugerowałbym wymuszania planu przy każdej regresji.
SentryOne nie zawsze przechwytuje dane lub parametry, więc nie mam wystarczających informacji. Jak mogę się upewnić, że SentryOne cały czas rejestruje parametry i plany wykonania?
Naprawdę nie możesz, ponieważ wszystko zależy od tego, jak wykonywane są twoje zapytania, jak je przechwytujemy i jak szybko działają. Często zapytania nie trwają wystarczająco długo, aby zostały w pełni przechwycone i musimy polegać na widokach zagregowanych statystyk zapytań/procedur SQL Server, które nie zbierają informacji o parametrach. Możesz zmienić ustawienia gromadzenia dla Top SQL Source, aby przechwytywać więcej i z większą częstotliwością, ale musisz zrównoważyć ilość gromadzonych danych z ilością dodatkowych informacji, które Ci kupują.
Czy mogę zapytać o informacje, aby zautomatyzować i wygenerować raporty?
Nie mamy nic do tego wymyślonego, ale pozwól, że zabiorę to z powrotem do zespołu i zobaczę, jakie opcje możemy wymyślić. Jedną z rzeczy, którymi się bawiłem podczas tego webinarium, było zbudowanie warunku doradczego, aby uchwycić rodzaje regresji, których szukamy, ale czas stał się czynnikiem.
Jak decydujemy, kiedy użyć
OPTION (RECOMPILE)
? , jak każdego dnia dostajemy różne plany dla różnych parametrów?
Powiedziałbym, że zacznij od zapytań, które najbardziej zmieniają się wraz z wrażliwością parametrów. Jeśli mam zapytanie, które czasami zajmuje 2 sekundy, ale czasami 30, a inne trwa od 4 do 6 sekund,
skoncentruję się na pierwszym.
Którego lepiej użyć,
OPTION (RECOMPILE)
lubQUERYTRACEON
, w przypadku podsłuchiwania parametrów.
Wolę
OPTION (RECOMPILE)
z dwóch powodów. Po pierwsze, to samodokumentowanie; nikt, kto czyta kod, nie będzie się zastanawiał, co on robi, ale nie każdy, kto czyta kod, będzie pamiętał numery TF, takie jak 4136. Po drugie, nie wymaga podwyższonych uprawnień – spróbuj użyćQUERYTRACEON
jako peon.
Czy istnieje możliwość powiadomienia lub zgłoszenia procedur, które trwają dłużej niż zwykle? Najbardziej interesują procedury o dużej liczbie.
Oczywiście można użyć warunku doradczego, ale może się to nieco skomplikować, ponieważ — w przypadku procedur, które czasami działają poniżej progu gromadzenia — konieczne byłoby porównanie migawek statystyk procedury DMV. Dodałem również przypomnienie na blogu o tym, ponieważ jest to coś, co pomogłem klientom wdrożyć w przeszłości.
Firma Microsoft ustawia automatyczne dostrajanie jako wartość domyślną dla Azure SQL Database, w tym automatyczną korektę planu. Czy wydaje ci się to dobrym pomysłem?
Zastrzeżę osąd, dopóki ja (lub niektórzy klienci) nie będę się z tym bawić. Podjęcie decyzji, jak dostroić, jest wystarczającym wyzwaniem dla śmiertelników; śmiertelnicy piszący oprogramowanie do strojenia dla ciebie wydają się co najmniej tak samo trudne, jeśli nie większe. Kiedy Andy zobaczył to pytanie, wspomniał mi, że przypomina mu ono SQL Server 2000 – marketing ówczesny był taki, że jest tak samodostrajający się, że nie będziemy już potrzebować DBA. To twierdzenie nie starzeje się dobrze.
Możliwość wybrania dwóch kropek na wykresie historii zapytań i porównania byłaby przyjemna.
Zgadzam się.
Bądź na bieżąco