Wprowadzenie
Od 1998 do początku 2014 r. SQL Server używał jednego estymatora kardynalności (CE), ale wprowadzał nowy poziom zgodności bazy danych z każdą nową główną wersją SQL Server (z wyjątkiem SQL Server 2008 R2). Natywne poziomy zgodności dla SQL Server są pokazane według głównych wersji SQL Server w Tabeli 1:
Wersja serwera SQL | Natywny poziom zgodności |
---|---|
Serwer SQL 7.0 | 70 |
Serwer SQL 2000 | 80 |
Serwer SQL 2005 | 90 |
SQL Server 2008 SQL Server 2008 R2 | 100 |
Serwer SQL 2012 | 110 |
Serwer SQL 2014 | 120 |
Serwer SQL 2016 | 130 |
Serwer SQL 2017 | 140 |
Serwer SQL 2019 | 150 |
Tabela 1:Wersje SQL Server i natywne poziomy zgodności
Pomiędzy SQL Server 7.0 i SQL Server 2012 nie było żadnego związku między poziomem zgodności bazy danych a estymatorem liczności, z którego korzystałyby zapytania w tej bazie danych. Dzieje się tak, ponieważ istniał tylko jeden estymator mocy, który otrzymał dużą aktualizację w 1998 roku. Poziom zgodności bazy danych był używany tylko do wstecznej kompatybilności funkcjonalnej oraz do włączania/wyłączania niektórych nowych funkcji w każdej nowej wersji SQL Server (zobacz to Odpowiedź Stack Exchange na przykłady, jak zmieniło się zachowanie między 80 a 90, prawdopodobnie najbardziej destrukcyjna zmiana). W przeciwieństwie do wersji pliku bazy danych SQL Server, poziom zgodności bazy danych można zmienić w dowolnym momencie, na dowolny obsługiwany poziom zgodności, za pomocą prostego polecenia ALTER DATABASE.
Domyślnie, jeśli utworzyłeś nowy w SQL Server 2012 poziom zgodności byłby ustawiony na 110, ale jeśli chcesz, możesz zmienić go na wcześniejszy poziom. Jeśli przywróciłeś kopia zapasowa bazy danych z instancji SQL Server 2008 na instancję SQL Server 2012, uaktualniłaby plikową wersję bazy danych, ale pozostawiłaby poziom zgodności tam, gdzie był na instancji SQL Server 2008 (chyba że był to 80, co spowodowałoby zaktualizuj do 90, minimalnej wersji obsługiwanej przez SQL Server 2012). Oprócz znajomości fundamentalnej różnicy między wersją pliku bazy danych a poziomem zgodności bazy danych, większość administratorów baz danych i programistów nie musiała się zbytnio przejmować poziomami zgodności bazy danych przed wydaniem SQL Server 2014. W wielu przypadkach poziom zgodności większości baz danych nigdy nie uległ zmianie po migracji do nowej wersji SQL Server. Zwykle nie powodowało to żadnych problemów, chyba że faktycznie potrzebna była nowa funkcja lub zachowanie, które uległo zmianie w najnowszym poziomie zgodności bazy danych.
Zmiany w SQL Server 2014
Ten stary stan rzeczy zmienił się radykalnie wraz z wydaniem SQL Server 2014. SQL Server 2014 wprowadził „nowy” estymator kardynalności, który był domyślnie włączony gdy baza danych miała poziom zgodności 120. W klasycznym oficjalnym dokumencie „Optymalizacja planów zapytań za pomocą programu SQL Server 2014 Cardinality Estimator” Joe Sack wyjaśnia tło i zachowanie tej zmiany w kwietniu 2014 roku. W wielu przypadkach większość zapytań działała szybciej przy użyciu nowej kardynalności estymator, ale dość często zdarzało się, że w przypadku niektórych zapytań wystąpiły poważne regresje wydajności w przypadku nowego estymatora kardynalności. Jeśli tak się stało, SQL Server 2014 nie miał tak wielu opcji łagodzenia problemów z wydajnością spowodowanych przez nowe CE. Oficjalny dokument Joego opisuje te opcje bardzo szczegółowo, ale zasadniczo ograniczono się do flag śledzenia na poziomie instancji lub wskazówek dotyczących zapytań na poziomie zapytania, aby kontrolować, który estymator liczności był używany przez optymalizator zapytań, chyba że chciałeś powrócić do poziomu zgodności 110 lub niższego .
Zmiany SQL Server 2016
W SQL Server 2016 wprowadzono opcje konfiguracji w zakresie bazy danych, które dają możliwość kontrolowania niektórych zachowań, które były wcześniej konfigurowane na poziomie instancji, za pomocą polecenia ALTER DATABASE SCOPED CONFIGURATION. W SQL Server 2016 te opcje obejmowały MAXDOP, LEGACY_CARDINALITY ESTIMATION, PARAMETER_SNIFFING i QUERY_OPTIMIZER_HOTFIXES. Dostępna była również opcja WYCZYŚĆ PROCEDURE_CACHE, która pozwala wyczyścić całą pamięć podręczną planu dla pojedynczej bazy danych.
Najistotniejsze w tym kontekście są opcje konfiguracji w zakresie bazy danych LEGACY_CARDINALITY i QUERY_OPTIMIZER_HOTFIXES. LEGACY_CARDINALITY ESTIMATION włącza starsze CE niezależnie od ustawienia poziomu zgodności bazy danych. Jest to odpowiednik flagi śledzenia 9481, ale wpływa tylko na daną bazę danych, a nie na całą instancję. Umożliwia ustawienie poziomu zgodności bazy danych na 130, aby uzyskać szereg korzyści funkcjonalnych i wydajnościowych, ale nadal używać starszej bazy danych CE w całej bazie danych (chyba że zostanie to zastąpione wskazówką dotyczącą zapytania na poziomie zapytania).
Opcja QUERY_OPTIMIZER_HOTFIXES jest odpowiednikiem flagi śledzenia 4199 na poziomie bazy danych. SQL Server 2016 włączy wszystkie poprawki optymalizatora zapytań przed SQL Server 2016 RTM w przypadku korzystania z poziomu zgodności bazy danych 130 (bez włączania flagi śledzenia 4199). Jeśli włączysz TF 4199 lub włączysz QUERY_OPTIMIZER_HOTFIXES, otrzymasz również wszystkie poprawki optymalizatora zapytań, które zostały wydane po SQL Server 2016 RTM.
Dodatek SP1 dla programu SQL Server 2016 wprowadził również wskazówki dotyczące zapytań USE HINT, które są łatwiejsze w użyciu, zrozumieniu i zapamiętaniu niż starsze wskazówki dotyczące zapytań QUERYTRACEON. Daje to jeszcze bardziej szczegółową kontrolę nad zachowaniem optymalizatora, które jest związane z poziomem zgodności bazy danych i używaną wersją estymatora kardynalności. Możesz zapytać sys.dm_exec_valid_use_hints, aby uzyskać listę prawidłowych nazw USE HINT dla dokładnej kompilacji SQL Server, którą używasz.
Zmiany SQL Server 2017
Nowa funkcja adaptacyjnego przetwarzania zapytań została dodana w SQL Server 2017 i jest domyślnie włączona w przypadku korzystania z poziomu zgodności bazy danych 140.
Microsoft stara się odejść od starej terminologii „nowego CE” i „starego CE”, ponieważ w każdej nowej głównej wersji SQL Server faktycznie istnieją zmiany i poprawki optymalizacji zapytań. Z tego powodu nie ma już jednego „nowego CE”. Zamiast tego Microsoft chce odwołać się do CE70 (domyślnie CE dla SQL Server 7.0 do SQL Server 2012), CE120 dla SQL Server 2014, CE130 dla SQL Server 2016, CE140 dla SQL Server 2017 i CE150 dla SQL Server 2019. Począwszy od SQL Server 2017 CU10, możesz użyć funkcji USE HINT, aby kontrolować to za pomocą wskazówek dotyczących zapytań. Na przykład:
/*...query...*/ OPTION (USE HINT('QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_130'));
… byłoby prawidłową wskazówką dotyczącą zapytania, aby wymusić estymację kardynalności CE130 dla konkretnego zapytania.
Zmiany w SQL Server 2019
SQL Server 2019 dodaje jeszcze więcej ulepszeń wydajności i zmian zachowania, które są domyślnie włączone, gdy baza danych korzysta z trybu zgodności 150. Najlepszym przykładem jest skalarne wstawianie UDF. Innym przykładem jest funkcja inteligentnego przetwarzania zapytań, która jest nadzbiorem adaptacyjnego przetwarzania zapytań w SQL Server 2017.
Dostępnych jest pięć nowych opcji USE HINT, w tym sposoby wyłączania trybu wsadowego lub wyłączania informacji zwrotnej o przydzieleniu pamięci adaptacyjnej, jak pokazano w Tabeli 2:
DISABLE_BATCH_MODE_ADAPTIVE_JOINS |
DISABLE_BATCH_MODE_MEMORY_GRANT_FEEDBACK |
DISABLE_INTERLEAVED_EXECUTION_TVF |
DISALLOW_BATCH_MODE |
QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_150 |
Tabela 2:Nowe opcje PODPOWIEDZI UŻYTKOWANIA
Dostępnych jest również szesnaście nowych opcji konfiguracji w zakresie bazy danych (od CTP 2.2), które zapewniają kontrolę na poziomie bazy danych nad większą liczbą elementów, na które mają wpływ również flagi śledzenia lub poziom zgodności bazy danych. Zapewnia bardziej szczegółową kontrolę nad zmianami wyższego poziomu, które są domyślnie włączone z poziomem zgodności bazy danych 150. Są one wymienione w Tabeli 3:
ACCELERATED_PLAN_FORCING | ELEVATE_RESUMABLE | ROW_MODE_MEMORY_GRANT_FEEDBACK |
BATCH_MODE_ADAPTIVE_JOINS | GLOBAL_TEMPORARY_TABLE_AUTO_DROP | TSQL_SCALAR_UDF_INLINING |
BATCH_MODE_MEMORY_GRANT_FEEDBACK | INTERLEAVED_EXECUTION_TVF | XTP_PROCEDURE_EXECUTION_STATISTICS |
BATCH_MODE_ON_ROWSTORE | ISOLATE_SECURITY_POLICY_CARDINALITY | XTP_QUERY_EXECUTION_STATISTICS |
DEFERRED_COMPILATION_TV | LIGHTWEIGHT_QUERY_PROFILING | |
ELEVATE_ONLINE | OPTIMIZE_FOR_AD_HOC_WORKLOADS |
Tabela 3:Nowe opcje konfiguracji w zakresie bazy danych
Wniosek
Migracja do nowoczesnej wersji SQL Server (czyli SQL Server 2016 lub nowszej) jest znacznie bardziej skomplikowana niż w przypadku starszych wersji SQL Server. Ze względu na zmiany związane z różnymi poziomami zgodności baz danych i różnymi wersjami estymatorów kardynalności, bardzo ważne jest, aby przemyśleć, zaplanować i przetestować poziom zgodności bazy danych, którego chcesz użyć w nowej wersji SQL Server. migrują istniejące bazy danych do.
Zalecanym procesem aktualizacji firmy Microsoft jest uaktualnienie do najnowszej wersji programu SQL Server, ale z zachowaniem poziomu zgodności źródłowej bazy danych. Następnie włącz magazyn zapytań w każdej bazie danych i zbieraj dane bazowe dotyczące obciążenia. Następnie ustaw poziom zgodności bazy danych na najnowszą wersję, a następnie użyj Query Store, aby naprawić regresję wydajności, wymuszając ostatni znany dobry plan.
Naprawdę chcesz uniknąć przypadkowej „ślepej” migracji, w której nie będziesz wiedział, jak to działa i jak Twoje obciążenie zareaguje na te zmiany. Zmiana poziomu zgodności bazy danych do odpowiedniej wersji i użycie odpowiednich opcji konfiguracyjnych w zakresie bazy danych, wraz z odpowiednimi wskazówkami dotyczącymi zapytań, gdy jest to absolutnie konieczne, jest niezwykle ważne w przypadku nowoczesnych wersji SQL Server.