To jest tekst przetłumaczony maszynowo.
Statystyki

Optymalizator zapytań używa statystyk do tworzenia planów zapytań poprawiających wydajność zapytań. W przypadku większości zapytań optymalizator zapytań generuje statystyki, które wystarczają do utworzenia planu zapytania o wysokiej jakości, ale w niektórych przypadkach trzeba utworzyć dodatkowe statystyki albo zmodyfikować projekt zapytania w celu osiągnięcia najlepszych wyników. W tym temacie omówiono koncepcje związane ze statystykami i podano wytyczne dotyczące efektywnego używania statystyk optymalizacji.

W tym temacie

Składniki i koncepcje

Statystyki

Statystyki służące do optymalizacji zapytań to obiekty, które zawierają informacje statystyczne dotyczące rozkładu wartości w co najmniej jednej kolumnie tabeli lub indeksowanego widoku. Optymalizator zapytań używa tych statystyk do szacowania kardynalności (liczby wierszy) w wynikach zapytania. Te szacowania kardynalności umożliwiają optymalizatorowi zapytań utworzenie planu zapytania o wysokiej jakości. Na przykład optymalizator zapytań może używać szacowań kardynalności w celu wybrania operatora przeszukiwania indeksu zamiast wymagającego większej ilości zasobów operatora skanowania indeksu, co spowoduje zwiększenie wydajności zapytania.

Każdy obiekt statystyk jest tworzony dla listy zawierającej co najmniej jedną kolumnę tabeli i zawiera histogram pokazujący rozkład wartości w pierwszej kolumnie. W obiektach statystyk dla wielu kolumn są także przechowywane informacje statystyczne dotyczące korelacji wartości z tych kolumn. Te statystyki korelacji (gęstości) są wyznaczane na podstawie liczby unikatowych wierszy zawierających wartości kolumn. Aby uzyskać więcej informacji dotyczących obiektów statystyk, zobacz temat DBCC SHOW_STATISTICS (języka Transact-SQL).

Filtrowane statystyki

Filtrowane statystyki mogą zwiększyć wydajność zapytań wybierających dane z dobrze zdefiniowanych podzestawów danych. W filtrowanych statystykach jest używany predykat filtru w celu wybrania podzestawu danych, który zostanie uwzględniony w statystyce. Dobrze zaprojektowane filtrowane statystyki mogą poprawić plan wykonania zapytania w porównaniu ze statystykami obejmującymi całą tabelę. Aby uzyskać więcej informacji dotyczących predykatu filtru, zobacz temat TWORZENIE statystyki (języka Transact-SQL). Aby uzyskać więcej informacji dotyczących tego, kiedy warto tworzyć filtrowane statystyki, zobacz sekcję Kiedy trzeba tworzyć statystyki w tym temacie. Aby zapoznać się z analizą przypadku, zobacz wpis w blogu Używanie filtrowanych statystyk z partycjonowanymi tabelami w witrynie SQLCAT w sieci Web.

Opcje statystyk

Można ustawić trzy opcje wpływające na czas i sposób tworzenia oraz aktualizowania statystyk. Te opcje można ustawiać tylko na poziomie bazy danych.

Opcja AUTO_CREATE_STATISTICS

Gdy opcja automatycznego tworzenia statystyk (AUTO_CREATE_STATISTICS) ma wartość ON (włączona), optymalizator zapytań w razie potrzeby tworzy statystyki dla poszczególnych kolumn w predykacie zapytania w celu poprawy szacowań kardynalności używanych w planie zapytania. Te jednokolumnowe statystyki są tworzone dla kolumn, które nie mają jeszcze histogramu w istniejącym obiekcie statystyk. Opcja AUTO_CREATE_STATISTICS nie określa, czy statystyki będą tworzone dla indeksów. Ta opcja nie powoduje także generowania filtrowanych statystyk. Powoduje ona wyłącznie stosowanie jednokolumnowych statystyk do całej tabeli.

Gdy optymalizator zapytań tworzy statystyki w wyniku użycia opcji AUTO_CREATE_STATISTICS, nazwy statystyk rozpoczynają się od przedrostka _WA. Za pomocą poniższego zapytania można ustalić, czy optymalizator zapytań utworzył statystyki dla kolumny predykatu zapytania.

SELECT OBJECT_NAME(s.object_id) AS object_name,
    COL_NAME(sc.object_id, sc.column_id) AS column_name,
    s.name AS statistics_name
FROM sys.stats AS s JOIN sys.stats_columns AS sc
    ON s.stats_id = sc.stats_id AND s.object_id = sc.object_id
WHERE s.name like '_WA%'
ORDER BY s.name;
Opcja AUTO_UPDATE_STATISTICS

Gdy opcja automatycznego aktualizowania statystyk (AUTO_UPDATE_STATISTICS) ma wartość ON (włączona), optymalizator zapytań ustala, czy statystyki są aktualne, a jeśli nie są, aktualizuje je, gdy są używane w zapytaniu. Statystyki stają się nieaktualne, gdy operacja wstawiania, aktualizowania, usuwania lub scalania zmieni rozkład danych w tabeli lub indeksowanym widoku. Optymalizator zapytań ustala, kiedy statystyki mogą być nieaktualne, zliczając modyfikacje danych od czasu ostatniej aktualizacji statystyk i porównując tę liczbę modyfikacji z wartością progową. Ta wartość progowa jest wyznaczana na podstawie liczby wierszy w tabeli lub indeksowanym widoku.

Przed skompilowaniem zapytania i przed wykonaniem buforowanego planu zapytania optymalizator zapytań sprawdza, czy istnieją nieaktualne statystyki. Przed skompilowaniem zapytania optymalizator zapytań używa kolumn, tabel i indeksowanych widoków w predykacie zapytania w celu ustalenia, które statystyki mogą być nieaktualne. Przed wykonaniem buforowanego planu zapytania program Aparat baz danych sprawdza, czy plan zapytania odwołuje się do aktualnych statystyk.

Opcja AUTO_UPDATE_STATISTICS jest stosowana do statycznych obiektów tworzonych dla indeksów, pojedynczych kolumn tabeli w predykatach zapytań oraz statystyk utworzonych za pomocą instrukcji CREATE STATISTICS. Ta opcja jest także stosowana do filtrowanych statystyk.

AUTO_UPDATE_STATISTICS_ASYNC

Opcja asynchronicznej aktualizacji statystyk (AUTO_UPDATE_STATISTICS_ASYNC) określa, czy optymalizator zapytań ma używać synchronicznych, czy asynchronicznych aktualizacji statystyk. Domyślnie opcja asynchronicznej aktualizacji statystyk jest wyłączona, a optymalizator zapytań aktualizuje statystyki synchronicznie. Opcja AUTO_UPDATE_STATISTICS_ASYNC jest stosowana do statycznych obiektów tworzonych dla indeksów, pojedynczych kolumn tabeli w predykatach zapytań oraz statystyk utworzonych za pomocą instrukcji CREATE STATISTICS.

Aktualizacje statystyk mogą być synchroniczne (ustawienie domyślne) lub asynchroniczne. W przypadku synchronicznych aktualizacji statystyk zapytania zawsze są kompilowane i wykonywane z użyciem aktualnych statystyk, ponieważ jeśli statystyki są nieaktualne, optymalizator zapytań czeka na zaktualizowanie statystyk, a dopiero potem kompiluje i wykonuje zapytanie. Z kolei w przypadku asynchronicznych aktualizacji statystyk zapytania są kompilowane z użyciem istniejących statystyk, nawet jeśli są one nieaktualne, przez co optymalizator zapytań może w tej sytuacji podczas kompilowania zapytania wybrać nieoptymalny plan zapytania. Zapytania skompilowane po wykonaniu aktualizacji asynchronicznych zostaną wykonane z użyciem zaktualizowanych statystyk.

Użycie statystyk synchronicznych należy rozważyć w przypadku wykonywania operacji zmieniających rozkład danych, takich jak obcinanie tabeli czy zbiorcze aktualizowanie dużego odsetka wierszy. Jeśli użytkownik nie aktualizuje statystyk po wykonaniu takiej operacji, użycie statystyk synchronicznych pozwoli zagwarantować, że statystyki zostaną zaktualizowane przed wykonaniem zapytań dotyczących zmienionych danych.

Użycie statystyk asynchronicznych należy rozważyć w celu poprawy przewidywalności czasów odpowiedzi na zapytania w następujących scenariuszach:

  • Aplikacja często wykonuje takie samo zapytanie, podobne zapytania albo podobne buforowane plany zapytań. Czasy odpowiedzi na zapytania mogą być bardziej przewidywalne w przypadku użycia asynchronicznych aktualizacji statystyk zamiast aktualizacji synchronicznych, ponieważ optymalizator zapytań będzie mógł wykonywać kolejne zapytania bez konieczności oczekiwania na zaktualizowanie statystyk. Dzięki temu będzie można uniknąć opóźnień w wykonywaniu części zapytań. Aby uzyskać więcej informacji dotyczących znajdowania podobnych zapytań, zobacz temat Finding and Tuning Similar Queries by Using Query and Query Plan Hashes.

  • Aplikacja napotyka zdarzenia upływu limitu czasu żądań klientów spowodowane oczekiwaniem na zaktualizowane statystyki podczas wykonywania co najmniej jednego zapytania. W niektórych przypadkach oczekiwanie na statystyki synchroniczne może powodować awarie aplikacji, dla których ustawiono krótkie limity czasu.

Ikona strzałki używana z łączem Powrót na górę stronyPowrót do początku

Kiedy trzeba tworzyć statystyki

Optymalizator zapytań zawsze tworzy statystyki następującymi metodami:

  1. Optymalizator zapytań tworzy statystyki dla indeksów tabel lub widoków, gdy indeks zostanie utworzony. Te statystyki są tworzone dla kolumn klucza indeksu. Jeśli indeks jest filtrowany, optymalizator zapytań tworzy filtrowane statystyki dla podzestawu wierszy określonego dla filtrowanego indeksu. Aby uzyskać więcej informacji dotyczących filtrowanych indeksów, zobacz tematy Tworzenie indeksów filtrowane i Utwórz indeks (języka Transact-SQL).

  2. Gdy opcja AUTO_CREATE_STATISTICS ma wartość ON (włączona), optymalizator zapytań tworzy statystyki dla pojedynczych kolumn w predykatach zapytań.

W przypadku większości zapytań te dwie metody tworzenia statystyk gwarantują tworzenie planów zapytań o wysokiej jakości. W niektórych przypadkach można poprawić plany zapytań, tworząc dodatkowe statystyki za pomocą instrukcji CREATE STATISTICS. Te dodatkowe statystyki mogą wykrywać korelacje statystyczne, których optymalizator zapytań nie uwzględnia podczas tworzenia statystyk dla indeksów lub pojedynczych kolumn. Między danymi w tabeli używanej przez aplikację mogą istnieć dodatkowe korelacje statystyczne, które po przekształceniu w obiekt statystyk mogą umożliwić optymalizatorowi zapytań ulepszenie planów zapytań. Na przykład filtrowane statystki dla podzestawu wierszy danych lub wielokolumnowe statystyki dla kolumn predykatu zapytania mogą ulepszyć plan zapytania.

W przypadku tworzenia statystyk za pomocą instrukcji CREATE STATISTICS zalecane jest pozostawienie wartości ON (włączona) opcji AUTO_CREATE_STATISTICS, dzięki czemu optymalizator zapytań będzie kontynuował okresowe tworzenie jednokolumnowych statystyk dla kolumn predykatu zapytania. Aby uzyskać więcej informacji dotyczących predykatów zapytań, zobacz temat Warunek wyszukiwania (języka Transact-SQL).

Tworzenie statystyk za pomocą instrukcji CREATE STATISTICS należy rozważyć, gdy występuje dowolna z następujących sytuacji:

  • Doradca dostrajania programu Aparat baz danych sugeruje utworzenie statystyk.

  • Predykat zapytania zawiera wiele skorelowanych kolumn, które nie są jeszcze uwzględnione w tym samym indeksie.

  • Zapytanie wybiera dane z podzestawu danych.

  • Dla danego zapytania brakuje statystyk.

Predykat zapytania zawiera wiele skorelowanych kolumn

Gry predykat zapytania zawiera wiele kolumn, które są połączone relacjami i zależnościami, statystyki dla wielu kolumn mogą poprawić plan zapytania. Statystyki dla wielu kolumn zawierają statystyki korelacji między kolumnami, nazywane gęstościami, które nie są dostępne w statystykach jednokolumnowych. Gęstości mogą poprawić jakość szacowań kardynalności w sytuacji, gdy wyniki zapytania zależą od relacji między danymi w wielu kolumnach.

Jeśli kolumny są już uwzględnione w jednym indeksie, obiekt wielokolumnowych statystyk już istnieje i nie trzeba tworzyć go ręcznie. Jeśli kolumny nie są jeszcze uwzględnione w jednym indeksie, można utworzyć statystyki wielokolumnowe, tworząc indeks dla tych kolumn lub używając instrukcji CREATE STATISTICS. Obsługa indeksu wymaga większej ilości zasobów systemowych niż obsługa obiektu statystyk. Jeśli aplikacja nie wymaga indeksu wielokolumnowego, można zmniejszyć zużycie zasobów systemu, tworząc obiekt statystyk bez tworzenia indeksu.

Podczas tworzenia statystyk wielokolumnowych kolejność kolumn w definicji obiektu statystyk ma wpływ na efektywność gęstości w zakresie tworzenia szacowań kardynalności. W obiekcie statystyk są przechowywane gęstości dla każdego prefiksu kolumn klucza w definicji obiektu statystyk. Aby uzyskać więcej informacji dotyczących gęstości, zobacz temat DBCC SHOW_STATISTICS (języka Transact-SQL).

Aby można było tworzyć gęstości, które będą użyteczne podczas tworzenia szacowań kardynalności, kolumny w predykacie zapytania muszą pasować do jednego z prefiksów kolumn w definicji obiektu statystyk. Na przykład poniższy kod powoduje utworzenie obiektu wielokolumnowych statystyk dla kolumn LastName, MiddleName i FirstName.

USE AdventureWorks2012;
GO
IF EXISTS (SELECT name FROM sys.stats
    WHERE name = 'LastFirst'
    AND object_ID = OBJECT_ID ('Person.Person'))
DROP STATISTICS Person.Person.LastFirst;
GO
CREATE STATISTICS LastFirst ON Person.Person (LastName, MiddleName, FirstName);
GO

W tym przykładzie obiekt statystyk LastFirst ma gęstości dla następujących prefiksów kolumn: (LastName), (LastName, MiddleName) i (LastName, MiddleName, FirstName). Gęstość nie jest dostępna dla prefiksu (LastName, FirstName). Jeśli w zapytaniu są używane kolumny LastName i FirstName, ale nie jest używana kolumna MiddleName, gęstość nie jest dostępna na potrzeby tworzenia szacowań kardynalności.

Zapytanie wybiera dane z podzestawu danych

Gdy optymalizator zapytań tworzy statystyki dla pojedynczych kolumn i indeksów, tworzy statystyki dla wartości znajdujących się we wszystkich wierszach. Gdy zapytanie wybiera dane z podzestawu wierszy, a podzestaw wierszy ma unikatowy rozkład danych, filtrowane statystyki mogą ulepszyć plany zapytań. Filtrowane statystyki można tworzyć przy użyciu instrukcji CREATE STATISTICS z klauzulą WHERE definiującą wyrażenie predykatu filtru.

Na przykład w bazie danych AdventureWorks2012 każdy produkt w tabeli Production.Product należy do jednej z czterech kategorii wymienionych w tabeli Production.ProductCategory: Bikes, Components, Clothing i Accessories. Każda z kategorii ma różny rozkład danych w zależności od wagi: waga rowerów (kategoria Bikes) należy do zakresu od 13,77 do 30,0, waga części (kategoria Components) należy do zakresu od 2,12 do 1050,00 (niektóre mają wagę równą NULL), waga ubrań (kategoria Clothing) zawsze jest równa NULL, a waga akcesoriów (kategoria Accessories) także zawsze jest równa NULL.

Gdy jako przykład będzie używana kategoria Bikes, filtrowane statystyki dla wszystkich wag rowerów będą dla optymalizatora zapytań dokładniejsze niż statystyki dla całej tabeli lub nieistniejące statystyki dla kolumny Weight i umożliwią mu zwiększenie jakości planu zapytania. Kolumna wag rowerów dobrze nadaje się do tworzenie filtrowanych statystyk, ale niekoniecznie nadaje się do utworzenia filtrowanego indeksu, jeśli liczba odnośników do wagi jest relatywnie mała. Poprawa wydajności związana z odnośnikami oferowanymi przez filtrowany indeks nie musi być na tyle duża, aby równoważyła koszty dodatkowej obsługi i przechowywania związane z dodaniem do bazy danych filtrowanego indeksu.

Następująca instrukcja tworzy filtrowaną statystykę BikeWeights dla wszystkich podkategorii kategorii Bikes. Wyrażenie filtrowanego predykatu definiuje rowery, wyliczając wszystkie podkategorie rowerów z porównaniem Production.ProductSubcategoryID IN (1,2,3). W predykacie nie można użyć nazwy kategorii Bikes, ponieważ jest ona przechowywana w tabeli Production.ProductCategory, a wszystkie kolumny w wyrażeniu filtru muszą znajdować się w jednej tabeli.

Transact-SQL
USE AdventureWorks2012;
GO
IF EXISTS ( SELECT name FROM sys.stats
    WHERE name = 'BikeWeights'
    AND object_ID = OBJECT_ID ('Production.Product'))
DROP STATISTICS Production.Product.BikeWeights;
GO
CREATE STATISTICS BikeWeights
    ON Production.Product (Weight)
WHERE ProductSubcategoryID IN (1,2,3);
GO

Optymalizator zapytań może użyć filtrowanej statystyki BikeWeights w celu ulepszenia planu zapytania dla następującego zapytania, które wybiera wszystkie rowery o wadze większej niż 25.

SELECT P.Weight AS Weight, S.Name AS BikeName
FROM Production.Product AS P
    JOIN Production.ProductSubcategory AS S 
    ON P.ProductSubcategoryID = S.ProductSubcategoryID
WHERE P.ProductSubcategoryID IN (1,2,3) AND P.Weight > 25
ORDER BY P.Weight;
GO

Zapytanie wskazuje brak statystyk

Jeśli błąd lub inne zdarzenie uniemożliwi optymalizatorowi zapytań utworzenie statystyk, optymalizator zapytań utworzy plan zapytania bez użycia tych statystyk. Optymalizator zapytań oznaczy te statystyki jako brakujące i podejmie próbę ich ponownego utworzenia podczas następnego wykonywania danego zapytania.

Gdy plan wykonania zapytania jest wyświetlany graficznie w programie SQL Server Management Studio, brakujące statystyki są wskazywane w formie ostrzeżeń (nazwa tabeli napisana czerwoną czcionką). Aby uzyskać więcej informacji, zobacz temat Graphically Displaying the Execution Plan Using SQL Server Management Studio. Ponadto monitorowanie klasy zdarzeń Missing Column Statistics (Brakujące statystyki kolumn) przy użyciu programu SQL Server Profiler umożliwia określenie, kiedy brakuje statystyk. Aby uzyskać więcej informacji, zobacz temat Błędy i ostrzeżenia zdarzenia kategorii (aparat bazy danych).

W przypadku braku statystyk wykonaj następujące kroki:

  • Sprawdź, czy opcje AUTO_CREATE_STATISTICS i AUTO_UPDATE_STATISTICS mają wartość ON (włączona).

  • Sprawdź, czy baza danych nie jest tylko do odczytu. Jeśli baza danych jest tylko do odczytu, optymalizator zapytań nie może zapisywać statystyk.

  • Utwórz brakujące statystyki, używając instrukcji CREATE STATISTICS.

Gdy dla bazy danych tylko do odczytu albo migawki tylko do odczytu brakuje statystyk lub są one nieaktualne, program Aparat baz danych tworzy i obsługuje tymczasowe statystyki w bazie danych tempdb. Gdy program Aparat baz danych tworzy tymczasowe statystyki, do nazw statystyk jest dołączany sufiks _readonly_database_statistic w celu odróżnienia ich od trwałych statystyk. Sufiks _readonly_database_statistic jest zastrzeżony dla statystyk generowanych przez program SQL Server. Skrypty obsługujące tymczasowe statystyki można tworzyć i odtwarzać w bazie danych do odczytu i zapisu. Gdy są używane skrypty, program Management Studio zmienia sufiks nazw statystyk z _readonly_database_statistic na _readonly_database_statistic_scripted.

Tworzyć i aktualizować tymczasowe statystyki może tylko program SQL Server. Można jednak usuwać tymczasowe statystyki i monitorować właściwości statystyk, używając tych samych narzędzi co w przypadku trwałych statystyk:

  • Usuń tymczasowe statystyki, używając instrukcji UPUŚĆ statystyki (języka Transact-SQL).

  • Monitoruj statystyki przy użyciu widoków wykazu sys.stats i sys.stats_columns. Widok sys_stats zawiera kolumnę is_temporary wskazującą, które statystyki są trwałe, a które tymczasowe.

Tymczasowe statystyki są przechowywane w bazie danych tempdb, więc ponowne uruchomienie usługi SQL Server powoduje utratę wszystkich tymczasowych statystyk.

Ikona strzałki używana z łączem Powrót na górę stronyPowrót do początku

Kiedy trzeba aktualizować statystyki

Optymalizator zapytań sprawdza, kiedy statystyki mogą być nieaktualne, a następnie aktualizuje je, gdy są potrzebne w planie zapytania. W niektórych przypadkach można ulepszyć plan zapytania, a przez to poprawić wydajność zapytania, aktualizując statystyki częściej niż ma to miejsce po ustawieniu wartości ON (włączona) dla opcji AUTO_UPDATE_STATISTICS. Statystyki można aktualizować za pomocą instrukcji UPDATE STATISTICS lub procedury składowanej sp_updatestats.

Aktualizowanie statystyk gwarantuje, że zapytania będą kompilowane z użyciem aktualnych statystyk. Jednak aktualizowanie statystyk powoduje ponowne kompilowanie zapytań. Zalecane jest, aby nie aktualizować statystyk zbyt często ze względu na kompromis w zakresie wydajności między ulepszaniem planów zapytań a czasem potrzebnym na ponowne kompilowanie zapytań. Te kompromisy są zależne od używanych aplikacji.

Zalecane jest, aby podczas aktualizowania statystyk za pomocą instrukcji UPDATE STATISTICS lub procedury składowanej sp_updatestats, pozostawić ustawioną wartość ON (włączona) opcji AUTO_UPDATE_STATISTICS, ponieważ dzięki temu optymalizator zapytań nadal będzie okresowo aktualizował statystyki. Aby uzyskać więcej informacji dotyczących sposobu aktualizowania statystyk dla kolumny, indeksu, tabeli lub indeksowanego widoku, zobacz temat Aktualizuj STATYSTYKĘ (języka Transact-SQL). Aby uzyskać informacje dotyczące sposobu aktualizowania statystyk dla wszystkich tabel zdefiniowanych przez użytkownika i tabel wewnętrznych, zobacz opis procedury składowanej sp_updatestats (języka Transact-SQL).

Aby ustalić, kiedy statystyki były aktualizowane po raz ostatni, należy użyć funkcji STATS_DATE.

Aktualizację statystyk warto rozważyć w następujących sytuacjach:

  • Wykonywanie zapytań długo trwa.

  • Operacje wstawiania są wykonywane w rosnących lub malejących kolumnach klucza.

  • Po operacjach konserwacji.

Wykonywanie zapytań długo trwa

Jeśli czas odpowiedzi na zapytanie jest długi lub nieprzewidywalny, przed wykonaniem dodatkowych kroków rozwiązywania problemów należy sprawdzić, czy w zapytaniach są używane aktualne statystyki. Aby uzyskać więcej informacji dotyczących rozwiązywania problemów z wolno działającymi zapytaniami, zobacz temat Checklist for Analyzing Slow-Running Queries.

Operacje wstawiania są wykonywane w rosnących lub malejących kolumnach klucza

Statystyki dla rosnących lub malejących kolumn klucza, takich jak kolumna IDENTITY lub kolumna sygnatur czasowych czasu rzeczywistego, mogą wymagać częstszego aktualizowania niż wykonywane przez optymalizatora zapytań. Operacje wstawiania powodują dołączanie nowych wartości do kolumn rosnących lub malejących. Liczba dodawanych wierszy może być zbyt mała, aby wyzwolić aktualizację statystyk. Jeśli statystyki są nieaktualne, a zapytanie wybiera dane z ostatnio dodanych wierszy, bieżące statystyki nie będą zawierać szacowań kardynalności dla tych nowych wartości. Może to spowodować używanie niedokładnych szacowań kardynalności i niską wydajność zapytań.

Na przykład zapytanie wybierające dane z najnowszych dat zamówień sprzedaży będzie mieć niedokładne szacowania kardynalności, jeśli statystyki nie zostaną zaktualizowane w celu uwzględnienia szacowań kardynalności dla najnowszych dat zamówień sprzedaży.

Po operacjach konserwacji

Zaktualizowanie statystyk warto rozważyć po wykonaniu procedur konserwacji zmieniających rozkład danych, takich jak obcinanie tabeli czy zbiorcze wstawianie dużego odsetka wierszy. Pomoże to uniknąć opóźnienia przetwarzania zapytań wykonywanych w przyszłości spowodowanego tym, że zapytania będą oczekiwać na automatyczne zaktualizowanie statystyk.

Operacje, takie jak odbudowywanie, defragmentowanie lub reorganizowanie indeksu nie powodują zmiany rozkładu danych. Dlatego nie trzeba aktualizować statystyk po wykonaniu operacji ALTER INDEX REBUILD, DBCC REINDEX, DBCC INDEXDEFRAG lub ALTER INDEX REORGANIZE. Jednak optymalizator zapytań aktualizuje statystyki po odbudowaniu indeksu tabeli lub widoku za pomocą instrukcji ALTER INDEX REBUILD lub DBCC DBREINDEX; ta aktualizacja statystyk jest skutkiem ubocznym operacji ponownego utworzenia indeksu. Optymalizator zapytań nie aktualizuje statystyk po wykonaniu operacji DBCC INDEXDEFRAG lub ALTER INDEX REORGANIZE.

Ikona strzałki używana z łączem Powrót na górę stronyPowrót do początku

Zapytania efektywnie używające statystyk

Pewne implementacje zapytań, takie jak zmienne lokalne i złożone wyrażenia w predykacie zapytania, mogą prowadzić do powstawania nieoptymalnych planów zapytań. Korzystanie z wytycznych dotyczących projektowania zapytań, które efektywnie używają statystyk, może pomóc w uniknięciu tego problemu. Aby uzyskać więcej informacji dotyczących predykatów zapytań, zobacz temat Warunek wyszukiwania (języka Transact-SQL).

Plany zapytań można ulepszyć, stosując się do wytycznych dotyczących projektowania zapytań, które efektywnie używają statystyk, w celu ulepszenia szacowań kardynalności dla wyrażeń, zmiennych i funkcji używany w predykatach zapytań. Gdy optymalizator zapytań nie zna wartości wyrażenia, zmiennej lub funkcji, nie wie, jakiej wartości ma szukać w histogramie, a przez to nie może pobrać z histogramu najlepszego szacowania kardynalności. Zamiast tego optymalizator zapytań tworzy szacowanie kardynalności na podstawie średniej liczby wierszy na unikatową wartość dla wszystkich próbkowanych wierszy w histogramie. Powoduje to używanie nieoptymalnych szacowań kardynalności i może obniżyć wydajność zapytań.

W poniższych wytycznych opisano sposób pisania zapytań umożliwiający ulepszenie planów zapytań przez poprawę szacowań kardynalności.

Ulepszanie szacowań kardynalności dla wyrażeń

Aby ulepszyć szacowania kardynalności dla wyrażeń, należy skorzystać z następujących wytycznych:

  • Gdy tylko jest to możliwe, należy upraszczać wyrażenia, używając w nich stałych. Optymalizator zapytań nie oblicza wszystkich funkcji i wyrażeń zawierających stałe przed ustaleniem szacowań kardynalności. Na przykład można uprościć wyrażenie ABS(-100) to 100.

  • Jeśli w wyrażeniu jest używanych wiele zmiennych, warto rozważyć utworzenie kolumny obliczanej dla wyrażenia, a następnie utworzenie statystyk albo indeksu dla tej kolumny obliczanej. Na przykład predykat zapytania WHERE PRICE + Tax > 100 może mieć lepsze szacowanie kardynalności, jeśli zostanie utworzona kolumna obliczana dla wyrażenia Price + Tax.

Ulepszanie szacowań kardynalności dla zmiennych i funkcji

Aby ulepszyć szacowania kardynalności dla zmiennych i funkcji, należy skorzystać z następujących wytycznych:

  • Jeśli w predykacie zapytania jest używana zmienna lokalna, warto rozważyć ponowne napisanie zapytania, tak aby zamiast zmiennej lokalnej był używany parametr. Wartość zmiennej lokalnej jest nieznana, gdy optymalizator zapytań tworzy plan wykonania zapytania. Gdy w zapytaniu jest używany parametr, optymalizator zapytań używa szacowania kardynalności dla pierwszej rzeczywistej wartości parametru przekazanej do procedury składowanej.

  • Warto rozważyć użycie standardowej lub tymczasowej tabeli do przechowywania wyników wieloinstrukcyjnych funkcji zwracających tabele. Optymalizator zapytań nie tworzy statystyk dla wieloinstrukcyjnych funkcji zwracających tabele. Dzięki temu podejściu optymalizator zapytań może tworzyć statystyki dla kolumn tabeli i używać ich do tworzenia lepszego planu zapytania. Aby uzyskać więcej informacji dotyczących wieloinstrukcyjnych funkcji zwracających tabele, zobacz temat Types of Functions.

  • Warto rozważyć użycie standardowej lub tymczasowej tabeli jako zamiennika zmiennych tabeli. Optymalizator zapytań nie tworzy statystyk dla zmiennych tabeli. Dzięki temu podejściu optymalizator zapytań może tworzyć statystyki dla kolumn tabeli i używać ich do tworzenia lepszego planu zapytania. Decyzja, czy należy użyć tymczasowej tabeli, czy zmiennej tabeli, jest wynikiem kompromisu. Zmienne tabeli używane w procedurach składowanych powodują mniejszą liczbę ponownych kompilacji procedury składowanej niż tymczasowe tabele. W zależności od aplikacji, użycie tymczasowej tabeli zamiast zmiennej tabeli może nie poprawić wydajności.

  • Jeśli procedura składowana zawiera zapytanie, w którym jest używany przekazany parametr, należy unikać zmieniania wartości parametru w procedurze składowanej przed użyciem go w zapytaniu. Szacowania kardynalności dla zapytania są oparte na przekazanej wartości parametru, a nie na zaktualizowanej wartości. Aby uniknąć zmiany wartości parametru, można ponownie napisać zapytanie, tak aby były w nim używane dwie procedury składowane.

    Na przykład procedura składowana Sales.GetRecentSales zmienia wartość parametru @date, gdy jest spełniony warunek @date is NULL.

    USE AdventureWorks2012;
    GO
    IF OBJECT_ID ( 'Sales.GetRecentSales', 'P') IS NOT NULL
        DROP PROCEDURE Sales.GetRecentSales;
    GO
    CREATE PROCEDURE Sales.GetRecentSales (@date datetime)
    AS BEGIN
        IF @date is NULL
            SET @date = DATEADD(MONTH, -3, (SELECT MAX(ORDERDATE) FROM Sales.SalesOrderHeader))
        SELECT * FROM Sales.SalesOrderHeader h, Sales.SalesOrderDetail d
        WHERE h.SalesOrderID = d.SalesOrderID
        AND h.OrderDate > @date
    END
    GO

    Jeśli pierwsze wywołanie procedury składowanej Sales.GetRecentSales przekaże dla parametru @date wartość NULL, optymalizator zapytań skompiluje procedurę składowaną z użyciem szacowania kardynalności dla wartości @date = NULL, nawet jeśli predykat zapytania nie jest wywoływany z wartością @date = NULL. Szacowanie kardynalności może być znacząco inne niż liczba wierszy w rzeczywistych wynikach zapytania. W wyniku tego optymalizator zapytań może wybrać nieoptymalny plan zapytania. Aby uniknąć tego problemu, można ponownie napisać procedurę składowaną, dzieląc ją na dwie procedury, tak jak pokazano poniżej:

    USE AdventureWorks2012;
    GO
    IF OBJECT_ID ( 'Sales.GetNullRecentSales', 'P') IS NOT NULL
        DROP PROCEDURE Sales.GetNullRecentSales;
    GO
    CREATE PROCEDURE Sales.GetNullRecentSales (@date datetime)
    AS BEGIN
        IF @date is NULL
            SET @date = DATEADD(MONTH, -3, (SELECT MAX(ORDERDATE) FROM Sales.SalesOrderHeader))
        EXEC Sales.GetNonNullRecentSales @date;
    END
    GO
    IF OBJECT_ID ( 'Sales.GetNonNullRecentSales', 'P') IS NOT NULL
        DROP PROCEDURE Sales.GetNonNullRecentSales;
    GO
    CREATE PROCEDURE Sales.GetNonNullRecentSales (@date datetime)
    AS BEGIN
        SELECT * FROM Sales.SalesOrderHeader h, Sales.SalesOrderDetail d
        WHERE h.SalesOrderID = d.SalesOrderID
        AND h.OrderDate > @date
    END
    GO

Ulepszanie szacowań kardynalności za pomocą wskazówek zapytań

Aby ulepszyć szacowania kardynalności dla zmiennych lokalnych, można użyć wskazówki zapytania OPTIMIZE FOR lub OPTIMIZE FOR UNKNOWN z opcją RECOMPILE. Aby uzyskać więcej informacji, zobacz temat Wskazówki kwerendy (języka Transact-SQL).

W przypadku niektórych aplikacji ponowne kompilowanie zapytania w czasie wykonywania może zajmować zbyt dużo czasu. Użycie wskazówki OPTIMIZE FOR może być pomocne, nawet jeśli nie jest używana opcja RECOMPILE. Na przykład można dodać opcję OPTIMIZE FOR do procedury składowanej Sales.GetRecentSales w celu określenia konkretnej daty. W poniższym przykładzie dodano opcję OPTIMIZE FOR do procedury Sales.GetRecentSales.

USE AdventureWorks2012;
GO
IF OBJECT_ID ( 'Sales.GetRecentSales', 'P') IS NOT NULL
    DROP PROCEDURE Sales.GetRecentSales;
GO
CREATE PROCEDURE Sales.GetRecentSales (@date datetime)
AS BEGIN
    IF @date is NULL
        SET @date = DATEADD(MONTH, -3, (SELECT MAX(ORDERDATE) FROM Sales.SalesOrderHeader))
    SELECT * FROM Sales.SalesOrderHeader h, Sales.SalesOrderDetail d
    WHERE h.SalesOrderID = d.SalesOrderID
    AND h.OrderDate > @date
    OPTION ( OPTIMIZE FOR ( @date = '2004-05-01 00:00:00.000'))
END;
GO

Ulepszanie szacowań kardynalności za pomocą przewodników planu

W przypadku niektórych aplikacji wytyczne dotyczące projektowania zapytań mogą nie mieć zastosowania, ponieważ nie będzie można zmienić zapytania albo użycie wskazówki zapytania RECOMPILE będzie powodować zbyt dużą liczbę operacji ponownego kompilowania. Za pomocą przewodników planu można określić inne wskazówki, takie jak USE PLAN, w celu kontrolowania zachowania zapytania podczas analizowania zmian w aplikacji wraz z jej dostawcą. Aby uzyskać więcej informacji dotyczących przewodników planu, zobacz temat Plan Guides.

Ikona strzałki używana z łączem Powrót na górę stronyPowrót do początku

Zobacz także

Odwołanie

Koncepcje

Znaczniki :


Page view tracker