W tym artykule przyjrzymy się konfiguracjom o zakresie bazy danych i automatycznej korekcji planu SQL Server 2017. Microsoft dodał nowe funkcje do SQL Server 2017, które poprawiły wydajność zapytań.
Wydajność zapytań SQL Server jest powiązana z jakością i dokładnością planu wykonania. Kiedy uruchamiamy zapytanie, optymalizator zapytań analizuje wiele planów wykonania, a następnie decyduje o optymalnym planie wykonania zapytania.
Starsze szacowanie liczebności: Estymator kardynacji przewiduje, ile wierszy zwróci zapytanie, a także określa alokację pamięci dla zapytania.
W programie SQL Server 2017 domyślna wersja modelu szacowania kardynacji to 14.0, ale jeśli chcesz użyć starszej wersji 7.0 modułu szacowania kardynacji, możesz to zrobić, zmieniając opcję Legacy Cardinality Estimation w Konfiguracjach z zakresem bazy danych sekcja.
Domyślna wartość szacowania Legacy Cardinality jest WYŁĄCZONA. Dlatego jeśli chcesz używać starszej wersji, musisz ją włączyć.
Alternatywnie możesz zmienić tę właściwość w T-SQL.
ZMIEŃ KONFIGURACJA ZAKRESU BAZY DANYCH LEGACY_CARDINALITY_ESTIMATION =OFF|ON;
Jeśli jednak włączysz to ustawienie, wpłynie to na wszystkie zapytania. W rezultacie może to spowodować pogorszenie wydajności zapytania. Aby temu zapobiec, możesz skorzystać ze wskazówki FORCE_LEGACY_CARDINALITY_ESTIMATION.
Kiedy uruchomimy to zapytanie w bazie danych WideWorldImporters, automatycznie użyje ono nowej wersji szacowania kardynalności.
SELECT [o].[IDKlienta], o.LastEditedBy , [o].[DataZamówienia] FROM Sprzedaż.Zamówienia oWHERE [o].[DataZamówienia]>='20140101'
Gdy dodamy FORCE_LEGACY_CARDINALITY_ESTIMATION do zapytania, optymalizator zapytań użyje poprzedniej lub najstarszej wersji oszacowania liczności.
MAXDOP : możemy ustawić maksymalny stopień równoległości dla pojedynczej bazy danych. Przed utworzeniem tej funkcji mogliśmy skonfigurować tylko poziom serwera MAXDOP.
Wskazówka dotycząca zapytania MAXDOP pozwala nam na równoległe uruchamianie zapytań.
ZMIEŃ KONFIGURACJA W ZAKRESIE BAZY DANYCH USTAW MAXDOP =4; Idź
Wąchanie parametrów: Kiedy czas wykonania zapytania zmienia się drastycznie i ta zmiana czasu jest związana z parametrem zapytania, nazywa się to sniffingiem parametru.
Teraz utworzymy procedurę składowaną w bazie danych AdventureWorks. Wyślemy różne parametry i porównamy plany wykonania.
DROP PROCEDURA JEŚLI ISTNIEJE Get_OrdersGOCREATE PROCEDURE Get_Orderes@ProductID INTASSELECT SalesOrderDetailID, OrderQtyFROM Sales.SalesOrderDetailWHERE ProductID =@ProductID;GO/********Nie używaj tego skryptu na serwerach produkcyjnych!********/ DBCC FREEPROCCACHE — zapytanie MarsEXEC Get_OrderID_OrderQty @ProductID=870DBCC FREEPROCCACHE — zapytanie VenusEXEC Get_OrderID_OrderQty @ProductID=897
Jak pokazano na poniższym obrazku, SQL Server generuje inny plan wykonania dla tego samego zapytania. Plan wykonania Query Mars zaleca indeks. Parametr zapytania zmienia optymalny plan wykonania.
Wykonaj to zapytanie i spójrz na plany wykonania.
DBCC FREEPROCCACHE — Zapytanie MarsEXEC Get_OrderID_OrderQty @ProductID=870 — Zapytanie VenusEXEC Get_OrderID_OrderQty @ProductID=897
Plan wykonania Query Venus jest taki sam, jak plan wykonania Query Mars. Jest to parametr sniffing, ponieważ buforowany plan wykonania jest kompilowany dla planu wykonania Query Mars. Z tego powodu Query Venus używa tego samego planu wykonania.
Teraz wyłączymy podsłuchiwanie parametrów i uruchomimy te same zapytania.
ZMIEŃ ZESTAW KONFIGURACJI ZAKRESU BAZY DANYCH PARAMETER_SNIFFING =OFF;DBCC FREEPROCCACHE--Zapytanie MarsEXEC Get_OrderID_OrderQty @ProductID=870--Zapytanie VenusEXEC Get_OrderID_OrderQty @ProductID=897
Przyjrzyjmy się:
Optymalizator SQL Server Query wygenerował optymalny plan wykonania dla Query Venus i Query Mars. Takie podejście zapewnia optymalną wydajność zapytania.
Istnieje kilka sposobów uniknięcia tego problemu:
- OPCJA (REKOMPILACJA)
- OPCJA (OPTYMALIZUJ DLA(@VARIABLE=NIEZNANE))
Automatyczna korekta planu
SQL Server 2017 zawiera nową funkcję o nazwie Automatyczna korekta planu. Kiedy wykonujemy zapytanie, optymalizator zapytań tworzy plan wykonania. Z pewnych powodów optymalizator kwerend wybiera niewłaściwe plany wykonania. Niektóre z powodów są następujące:
- Zapytanie, które nie spełnia kryteriów wydajności
- Nieaktualne statystyki
- Nieodpowiednie indeksy
Gdy optymalizator zapytań SQL Server zdecyduje się zmienić plan wykonania i ten plan wykonania obniży wydajność, wydajność zapytania nazywana jest regresją planu. Nowa funkcja jest dostępna w SQL Server 2016. To narzędzie pomaga w monitorowaniu i rozwiązywaniu problemów z wydajnością zapytań, a jednocześnie przechowuje metryki wydajności i liczniki wykonywania zapytań.
Możemy włączyć te opcje we właściwościach bazy danych.
Teraz zrobimy demo tej funkcji. Przede wszystkim wyczyść pamięć podręczną procedur i utwórz procedurę składowaną.
/****************************************Nie używaj tego skryptu w serwery produkcyjne*******************************************/USE WideWorldImportersALTER BAZA DANYCH WideWorldImporters SET QUERY_STORE =WŁ; ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR ALLDBCC FREEPROCCACHE — to polecenie wyczyści całą pamięć podręczną procedur w programie SQL Server. Nie próbuj w środowisku produkcyjnym -- ALTER DATABASE WideWorldImporters SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN =OFF); UPUŚĆ PROCEDURA JEŚLI ISTNIEJE Test_CoddingSight2 GO CREATE PROC Test_CoddingSight2 @Id AS INT AS wybierz sumę ([CenaJednostkowa]*[Ilość]) z Sales.OrderLines O INNER JOIN sales.Orders o1 ON o1.OrderID =o.OrderID gdzie o.PackageTypeID =@ Identyfikator
Na tym etapie wykonamy tę procedurę z różnymi parametrami i znajdziemy różnicę czasu wykonania.
--Zapytanie AlphaDBCC FREEPROCCACHE EXEC Test_CoddingSight2 7GO 80DBCC FREEPROCCACHE EXEC Test_CoddingSight2 ----Zapytanie BetaEXEC Test_CoddingSight2 7GO 80
Jak widać, pierwsze zapytanie zostało wykonane w 12 sekund, drugie w 33 sekundy. Powodem tej dramatycznej różnicy jest to, że optymalizator zapytań wybiera nieodpowiedni plan wykonania dla zapytania Beta.
Porównajmy plany wykonania Query Alpha i Query Beta.
Plan wykonania Query Alpha
Plan wykonania zapytania Beta
Na powyższych obrazach optymalizator zapytań tworzy różne plany wykonania dla tego samego zapytania. Kiedy spojrzymy na Najczęstsze zapytania zużywające zasoby , widzimy, że Query Beta zużywa więcej zasobów niż Query Alpha.
Poniższe zapytanie zwróci szczegółowe informacje na temat zaleceń dotyczących strojenia.
SELECT nazwa, powód, wynik,JSON_VALUE(szczegóły, '$.implementationDetails.script') jako skrypt, szczegóły.* FROM sys.dm_db_tuning_recommendations CROSS APPLY OPENJSON(szczegóły, '$.planForceDetails') WITH ( query_id int '$ .queryId', regressed_plan_id int '$.regressedPlanId', last_good_plan_id int '$.recommendedPlanId') as detailsWHERE JSON_VALUE(state, '$.currentValue') ='Active'
Kolumna przyczyny pokazuje, dlaczego musimy zastosować to zalecenie.
Teraz ponownie uruchomimy Query Alpha i Query Beta z włączoną automatyczną korektą planu.
/****************************************Nie używaj tego skryptu na serwerach produkcyjnych*********************************************/ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR ALLDBCC FREEPROCCACHE /**************************************** Włącz automatyczną korektę planu *****************************************/ALTER BAZA DANYCH WideWorldImporters SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN =NA); --Query AlphaDBCC FREEPROCCACHE EXEC Test_CoddingSight2 7GO 80DBCC FREEPROCCACHE EXEC Test_CoddingSight2 --- Zapytanie BetaEXEC Test_CoddingSight2 7GO 80
Po tej demonstracji plan wykonania Query Alpha zostanie zastosowany do Query Beta. Ponadto czasy wykonania Query Alpha i Query Beta są zbliżone. Poniższe zapytanie zwróci stan automatycznej korekty planu.
SELECT nazwa, powód, wynik,JSON_VALUE(stan, '$.currentValue') jako status,JSON_VALUE(szczegóły, '$.implementationDetails.script') jako skrypt, szczegóły.* FROM sys.dm_db_tuning_recommendations CROSS APPLY OPENJSON(szczegóły , '$.planForceDetails') WITH ( query_id int '$.queryId', regressed_plan_id int '$.regressedPlanId', last_good_plan_id int '$.recommendedPlanId') as detailsWHERE JSON_VALUE(state, '$)'=current'Value /pre>
Ponadto niektóre informacje graficzne możemy znaleźć w Zapytaniach z wymuszonymi planami . Ten wykres definiuje plany i zapytania wymuszone.
Referencje
Automatyczna korekta planu w SQL Server 2017
Szacowanie liczności