Database
 sql >> Baza danych >  >> RDS >> Database

Różne plany dla identycznych serwerów

W moim ostatnim poście, „Wiele planów dla „identycznego” zapytania, mówiłem o przypadku, w którym otrzymujesz dwa różne plany dla tego, co uważasz za to samo zapytanie, a także o przypadku, gdy otrzymujesz dwie kopie taki sam plan (a może nawet o tym nie wiedzieć). Jak tam zbadaliśmy, „identyczny” może być dość mocnym słowem.

Innym scenariuszem, który powoduje pętlę, jest przypadek, w którym przywracają bazę danych na inny serwer — powiedzmy przywracają produkcyjną bazę danych na „identyczny” serwer testowy — i uzyskują różne charakterystyki wydajności lub różne plany dla tego samego zapytania (nie cytuje tym razem – naprawdę mówię o naprawdę identycznych zapytaniach).

Czy serwery naprawdę są „identyczne”?

Ci goście mogą wyglądać podobnie, ale nie są identyczne.

Jeśli natkniesz się na ten scenariusz, pierwszą rzeczą, którą musisz zadać sobie, jest to, czy te dwa serwery naprawdę są identyczne. Kilka rzeczy do sprawdzenia:

  • Wersja – Wiele zmian w zachowaniu optymalizatorów i zapytań jest wprowadzanych za pośrednictwem dodatków Service Pack i aktualizacji zbiorczych. Często widziałem ludzi mówiących:„Cóż, oboje mają 2008 rok!” – kiedy w rzeczywistości jeden był 2008, a drugi 2008 R2, lub były na różnych dodatkach Service Pack lub nawet na poziomach aktualizacji zbiorczych. Ponieważ wiele osób czytających @@VERSION myli informacje o dodatku Service Pack dla systemu operacyjnego z informacjami o dodatku Service Pack dla programu SQL Server, powiedziałbym, że lepiej jest:

    SELECT SERVERPROPERTY (N'ProductVersion' );

    Nie mogę wystarczająco podkreślić, jak ważne jest używanie dokładnie tej samej wersji do wykonywania prawdziwych testów „jabłka na jabłka”. Jeśli używasz SQL Server 2012 lub nowszego, możesz sprawdzić nasze wpisy dotyczące kompilacji (SQL Server 2012 | SQL Server 2014), aby określić dodatek Service Pack lub aktualizację zbiorczą wymaganą w celu upewnienia się, że wersje są zgodne.

  • Wydanie – Chociaż miejmy nadzieję, że używasz tej samej edycji na obu serwerach (lub równoważnych, ponieważ oprócz licencjonowania, programista i ocena są takie same jak Enterprise), tutaj niedopasowania mogą prowadzić do bardzo różnych zachowań. Na przykład różne wersje mają różne możliwości obliczeniowe dla różnych funkcji, a ponadto istnieją subtelniejsze rzeczy, takie jak możliwość korzystania z widoku indeksowanego bez wskazówki NOEXPAND lub wykonywania zmian schematu lub konserwacji indeksu w trybie online. Możesz porównać wydania, używając:

    SELECT SERVERPROPERTY (N'Edition' );

  • Liczba procesorów – SQL Server zdecydowanie wykorzystuje liczbę harmonogramów dostępnych podczas procesu tworzenia planu wykonania i nie można zaprzeczyć, że liczba rdzeni może wpływać na rzeczywistą wydajność środowiska uruchomieniowego (pomińmy szybkość zegara, ponieważ rzadko jest to istotny czynnik w zapytaniu występ). Nie tylko sprawdzaj liczbę rdzeni fizycznie zainstalowanych na podstawowym serwerze, ale także sprawdź w dzienniku błędów programu SQL Server liczbę procesorów, których program SQL Server może faktycznie używać dzięki licencjonowaniu. Nawet pomijając surową liczbę rdzeni, w systemie NUMA sztuczne ograniczenia mogą prowadzić do bardzo różnych profili wydajności. Więcej informacji można znaleźć w niedawnym poście Brenta Ozara „Why Core-Based Licensing Matters for Performance Tuning”. Z tym wiąże się również edycja, ponieważ w SQL Server 2012 i 2014 wersja Standard Edition może używać tylko 16 rdzeni, bez względu na to, jakie ustawienia lub sprzęt fizyczny mogą skłaniać do przekonania. Inne ustawienia, które mogą w różny sposób wpływać na wybór planu opartego na procesorze i wydajność, obejmują Resource Governor, parametr MAXDOP dla całego serwera, koligację procesora i próg kosztów dla równoległości.
  • Ilość pamięci – Podobnie jak procesory, optymalizator dokonuje wyboru planu na podstawie ilości dostępnej pamięci. Podobnie jak w przypadku procesorów, nie mówię tylko o ilości pamięci RAM zainstalowanej w systemie, ale o ilości pamięci przyznanej SQL Serverowi io ​​tym, ile faktycznie wykorzystuje. Sprawdź ustawienia maksymalnej pamięci serwera, ale także liczniki wydajności dla pamięci całkowitej i docelowej, a nawet DBCC MEMORYSTATUS. Inne rzeczy, które możesz chcieć przejrzeć, obejmują ustawienia Resource Governor i Zablokuj strony w pamięci. Istnieje również ustawienie, które, jeśli różni się między dwoma serwerami, może mieć znaczący wpływ na ilość pamięci podręcznej planu jest używanej dla tego samego zestawu zapytań:optymalizuj pod kątem obciążeń ad hoc. Kimberly Tripp ma świetny post na ten temat:Zaplanuj pamięć podręczną i optymalizuj pod kątem obciążeń adhoc. Wreszcie, jeśli serwer jest wirtualny, pamiętaj, że środowisko może tutaj odgrywać pewną rolę – zwłaszcza gdy ustawienia pamięci VM nie są zgodne z produkcją lub są dynamiczne.
  • Pula buforów / pamięć podręczna planów – Kiedy przywracasz bazę danych na serwerze testowym, jest kilka rzeczy, które po prostu nie są gotowe od razu. Pula buforów nie zawiera żadnych danych, które mogły istnieć na serwerze źródłowym — więc będą wymagane dodatkowe operacje we/wy, aby przygotować dane do pamięci przy pierwszym zapytaniu. A jeśli pula buforów jest ograniczona inaczej niż produkcja ze względu na niektóre z powyższych czynników, może nie być możliwe osiągnięcie tych samych wzorców wydajności nawet po wielokrotnym uruchomieniu zapytania – mówi o tym Paul White (@SQL_Kiwi w swojej odpowiedzi na Administratorzy baz danych. Ponadto pamięć podręczna planów nie będzie zawierać żadnego z planów, które istniały w produkcji, więc przynajmniej – nawet jeśli ten sam plan zostanie ostatecznie skompilowany (co może się nie zdarzyć z powodu innych parametrów niż podczas kompilacji planu na oryginale serwer) – poniesiesz dodatkowe koszty kompilacji. A te mogą się zmienić, jeśli masz również flagi śledzenia mające wpływ na plan.
  • Podsystem dysków – Chociaż szybkość i rozmiar używanych dysków nie wpłyną bezpośrednio na wybór planu, z pewnością mogą wpłynąć na obserwowaną wydajność, co może sprawić, że będziesz się zastanawiać, dlaczego to samo zapytanie, z tym samym planem, działa o wiele szybciej na jednym system niż inne. We/Wy jest zwykle największym wąskim gardłem SQL Server i dość rzadko zdarza się, aby serwer testowy rzeczywiście miał dokładnie ten sam podsystem, co jego odpowiednik produkcyjny. Jeśli więc widzisz różnice w wydajności między dwoma systemami, a plany i inne elementy sprzętowe są takie same, może to być kolejne najlepsze miejsce do sprawdzenia. I nie zapominaj, że począwszy od SQL Server 2014, Resource Governor może nakładać ograniczenia na wydajność we/wy.
  • Flagi śledzenia – Sprawdź listę globalnych flag śledzenia ustawionych na obu serwerach; istnieje kilka, które mogą wpływać na optymalizację, zachowanie planu i postrzeganą wydajność, nawet jeśli wszystkie powyższe ustawienia są identyczne. Oto 10 popularnych i godnych uwagi (chociaż absolutnie nie jest to poparcie dla włączenia któregokolwiek z nich bez dokładnych testów regresji):

    Flaga Wyjaśnienie
    2301 Zmusza optymalizatora do spędzenia więcej czasu na szukaniu optymalnego planu.
    2312 Wymusza nowy estymator mocy obliczeniowej SQL Server 2014.
    2335 Powoduje bardziej konserwatywne przydziały pamięci.
    2453 Wymusza OPCJE (RECOMPILE) dla zapytań odwołujących się do zmiennych tabeli.
    2861 Pozwala SQL Serverowi buforować trywialne / bezkosztowe plany.
    4136 Efektywnie dodaje OPTYMALIZUJ DLA NIEZNANYCH do wszystkich zapytań (aby uniemożliwić podsłuchiwanie parametrów).
    4199 Parasol zawierający mnóstwo poprawek optymalizatora.
    8744 Wyłącza wstępne pobieranie dla zagnieżdżonych pętli.
    9481 Wyłącza nowy estymator kardynalności SQL Server 2014.


    Ta lista flag śledzenia nie jest w żaden sposób wyczerpująca; jest wiele innych, w tym te nieudokumentowane, o których proszono, abym nie wspominał. Jeśli używasz innych osób niewymienionych powyżej (i nie możesz wyjaśnić dlaczego), możesz znaleźć wskazówki w KB #920093, KB #2964518, flagi śledzenia (MSDN) lub flagi śledzenia w programie SQL Server (TechNet). Znajdziesz również cenne informacje w różnych postach Paula White'a, tutaj lub na sql.kiwi.

  • Współczesność – Przypuszczalnie system testowy jest używany do rzeczy innych niż to, co aktualnie testujesz. I jeśli nie wykonujesz jakiejś powtórki, prawdopodobnie ma ona również bardzo inny profil obciążenia. Te różnice w obciążeniu mogą oczywiście mieć bezpośredni wpływ na dostępność zasobów do obsługi testowanych żądań, a z kolei na postrzeganą wydajność tych żądań. Nie zapomnij sprawdzić innych usług, które mogą nie istnieć w środowisku produkcyjnym lub istnieją, ale są używane w inny sposób (takie jak usługi Analysis Services, Reporting Services, usługi systemu Windows, a nawet własne aplikacje). I odwrotnie, mogą istnieć takie usługi w środowisku produkcyjnym, które wpływają na wydajność, lub dodatkowe obciążenie samej instancji, które nie jest naśladowane w teście:poza rzeczywistym obciążeniem produkcyjnym, pomyśl o takich rzeczach, jak śledzenie, rozszerzone zdarzenia, monitorowanie o dużym wpływie, śledzenie zmian, przechwytywanie zmian danych, audyt, broker usług, konserwacja indeksów, zadania tworzenia kopii zapasowych, kontrole DBCC, dublowanie, replikacja, grupy dostępności, a lista jest długa…

Czy bazy danych są nadal „identyczne”?

Zakładając, że wszystkie zmienne dotyczące sprzętu i obciążenia są wystarczająco dobrze dopasowane, zapewnienie, że bazy danych pozostaną takie same, nadal może być trudne. Jeśli wykonujesz kopię zapasową / przywracanie w systemie testowym, nowa baza danych zaczyna się identycznie jak źródło (z wyjątkiem fizycznej lokalizacji i bezpieczeństwa). Ale gdy tylko zaczniesz go dotykać w jakikolwiek sposób, bardzo szybko odbiega od kopii produkcyjnej, ponieważ możesz wykonać dowolną lub wszystkie z następujących czynności:

  • Zmień dane, schemat lub jedno i drugie.
  • Nieumyślnie rozpocznij automatyczną aktualizację statystyk.
  • Ręcznie dodawaj, defragmentuj lub przebudowuj indeksy albo twórz lub aktualizuj statystyki.
  • Zmień ustawienia bazy danych, takie jak poziom zgodności, poziom izolacji, wymuszona parametryzacja, selektywne indeksy XML lub dowolną opcję o nazwie „Auto”-. (Do diabła, nawet lokalizacje plików danych i dzienników oraz ustawienia wzrostu mogą wpływać na wydajność zapytań, w tym tempdb).
  • Opróżnij pamięć podręczną planu, pulę buforów lub jedno i drugie, bezpośrednio lub jako efekt uboczny innych zdarzeń (takich jak RECONFIGURE lub ponowne uruchomienie usługi).

Ponadto, gdy zaczniesz generować nowe plany zapytań, jeszcze przed wprowadzeniem którejkolwiek z powyższych zmian, musisz pamiętać, że mogą one opierać się na danych, które są inne niż dane wykorzystywane do generowania planów dla tych samych zapytań w środowisku produkcyjnym. Na przykład kardynalność, gdy plan był kompilowany w środowisku produkcyjnym, mogła znacznie przekrzywić się między tym punktem a czasem utworzenia kopii zapasowej, co oznacza, że ​​nowy plan zostanie wygenerowany na podstawie różnych statystyk i informacji histogramu.

Te rzeczy różnią się jeszcze bardziej, jeśli w rzeczywistości nie jest to niedawne przywracanie — ale raczej dwa schematy i zestawy danych, które są synchronizowane w inny sposób (na przykład ręczne wdrażanie zmian schematu i/lub danych, a nawet replikacja). Ze względu na ograniczenia miejsca na dysku mogłeś również pobrać tylko podzbiór danych produkcyjnych lub nawet klon zawierający tylko statystyki – te różnice w danych prawie na pewno doprowadzą do różnych charakterystyk wydajności dla wszystkich zapytań z wyjątkiem najprostszych, nawet jeśli to zrobisz powodzenia i zdobądź te same plany dla niektórych.

Czy zapytania są naprawdę „identyczne”?

Nawet jeśli wszystko powyżej się sprawdzi, nadal istnieją scenariusze, w których otrzymujesz inny plan z powodu ustawień sesji (możesz używać innej kopii programu SSMS, z różnymi ustawieniami lub całkowicie innego narzędzia klienta) lub różnych domyślnych schematów ( na przykład możesz łączyć się z serwerem testowym jako inny login Windows lub SQL). Dużo o tym mówiłem w poprzednim poście.

Wniosek

Chociaż istnieją sposoby na złagodzenie niektórych różnic (sprawdź DBCC OPTIMIZER_WHATIF, aby oszukać serwer testowy, aby uwierzył w fenomenalne rzeczy dotyczące podstawowego sprzętu), prawda jest taka, że ​​bardzo trudne będzie sprawienie, aby dwa serwery działały niezawodnie i konsekwentnie, i że istnieją potencjalnie dziesiątki powodów, dla których możesz uzyskać różne plany lub inną wydajność na dwóch podobnych (lub nawet identycznych) serwerach.

Czy masz jakieś szczególne sztuczki? Czy masz jakieś rozdzierające problemy z powyższymi pomysłami (lub innymi, o których zapomniałem wspomnieć)? Podziel się w komentarzach poniżej!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przechowywana procedura uzyskiwania statusu indeksów we wszystkich bazach danych

  2. Opcje dostrajania wydajności bazy danych SQL Azure

  3. Odkrywanie testów jednostkowych Java za pomocą JUnit Test Framework

  4. Czy Twoja baza danych jest zabezpieczona? Pomyśl jeszcze raz

  5. SCD typu 1