Dlaczego program SQL Server nie wykonuje histogramów statystyk kolumn złożonych?

10

SQL Server ma coś, co nazywa się „statystyką wielokolumnową”, ale nie jest tak, jak mogłoby się wydawać.

Rzućmy okiem na poniższą przykładową tabelę:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

Dzięki temu tworzone są dwie statystyki dotyczące dwóch indeksów:

Statystyki dla BadIndex:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

Statystyki dla indeksu klastrowego:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

(Wypełniłem tabelę losowymi danymi przykładowymi, w których około jedna dziesiąta wierszy nie jest zarchiwizowana. Następnie przeprowadziłem aktualizację statystyk pełnego skanowania).

Dlaczego histogram statystyk dwukolumnowych używa tylko jednej kolumny? Wiem, że wiele osób pisało o to, że nie , ale co to uzasadnienie? W takim przypadku cały histogram jest o wiele mniej przydatny, ponieważ pierwsza kolumna ma tylko dwie wartości. Dlaczego statystyki byłyby tak arbitralnie ograniczone?

Pamiętaj, że to pytanie nie dotyczy wielowymiarowych histogramów, które są zupełnie inną bestią. Chodzi o jednowymiarowe histogramy, przy czym jeden wymiar jest krotkami zawierającymi odpowiednie, wiele kolumn.

Jan
źródło

Odpowiedzi:

8

tło

Obecny model SQL Server używa tylko histogramów jednokolumnowych i informacji o gęstości wielokolumnowej. Histogramy jednokolumnowe służą do oszacowania selektywności dla odpowiednich predykatów, np . a = 1Lub b > 50. Kwerenda z wieloma predykatami po prostu łączy poszczególne selektywności (z założeniami), aby uzyskać oszacowaną ogólną selektywność.

Na przykład zobacz mój artykuł Oszacowanie liczności: łączenie statystyk gęstości

Gęstość wielokolumnowa dodatkowo informuje model, zapewniając słabą informację o korelacji dla wielu predykatów równości i grupując liczności dla agregacji.

Statystyki powiązane z indeksami są oportunistycznym dodatkiem do tego modelu: silnik może również zbierać statystyki (zwykle pełne skanowanie) podczas tworzenia indeksu. SQL Server automatycznie konstruuje histogram kolumny wiodącej i informacje o gęstości dla pozostałych kluczy.

Histogramy dla niepalących czołowych kolumn w indeksie mogą być wykonane na żądanie automatycznie przez procesor zapytań, lub korzystając sp_createstatsz @indexonlyopcji (między innymi).

Histogramy wielokolumnowe

Założenia przyjęte podczas łączenia statystyk jednokolumnowych (jak wyżej) mogą wystarczająco dobrze modelować rzeczywistość danych. W wielu przypadkach dostępne opcje (wykładnicze wycofanie, niezależność, minimalna selektywność) dają oszacowanie „wystarczająco dobre”.

Filtrujemy również statystyki (i indeksy) jako naturalne rozwiązanie dla indeksów kolumn wiodących o niskiej liczności, takich jak w przykładzie z pytaniem. Doprowadzenie ich do logicznej skrajności prowadzi nas do wielowymiarowych statystyk, o których nie chodzi w tym pytaniu.

Gdy dostępne opcje modelowania nie są w stanie zapewnić odpowiedniego oszacowania, histogram wielokolumnowy może rzeczywiście dać lepsze oszacowanie selektywności dla odpowiednich predykatów indeksu, w niektórych przypadkach. Istnieją pewne trudności związane z łączeniem różnych typów danych w różnych kolumnach, ale nic nie do pokonania.

Potrzebujemy również histogramu dla każdego poziomu klawiszy indeksu (dla najlepszych wyników); tak więc dla indeksu (a, b, c)oznaczałoby to włączenie histogramów (a, b)i (a, b, c)oprócz bieżącego histogramu jednokolumnowego (a).

Mechanizm zastosowany do wykrywania nieaktualnych statystyk również musiałby zostać zmodyfikowany, aby zachować zmienione histogramy wielokolumnowe. Te histogramy najprawdopodobniej zostaną przebudowane częściej niż statystyki jednokolumnowe, po prostu dlatego, że wpływają na nie modyfikacje większej liczby kolumn.

Wszystko to zwiększa rozmiar, złożoność i koszty utrzymania.

Wielokolumnową statystykę można symulować (w ograniczonym zakresie), korzystając ze statystyki utworzonej na starannie skonstruowanej kolumnie obliczeniowej odwołującej się do wielu kolumn. Kwerenda musiałaby zawierać predykat w kolumnie obliczeniowej (lub dokładne dopasowanie tekstowe dla podstawowej formuły), aby skorzystać z tej statystyki. Prawdopodobnie istnieją tylko bardzo ograniczone sytuacje, w których takie podejście jest praktyczne. Niemniej jednak ma kilka takich samych problemów z implementacją, jak w przypadku automatycznych histogramów wielokolumnowych.

Ostatecznie jedynymi osobami, które mogą z całą pewnością powiedzieć, dlaczego SQL Server nie obsługuje statystyk wielokolumnowych, byli sami projektanci. Jeśli uważasz, że możesz uzasadnić ulepszenie produktu w tym obszarze dzięki szerokiemu zakresowi zastosowania, możesz zasugerować go w Connect lub za pośrednictwem zwykłego kanału wsparcia.

Notatka

W takim przypadku cały histogram jest o wiele mniej przydatny, ponieważ pierwsza kolumna ma tylko dwie wartości

Histogram nadal dostarcza użytecznych informacji o rozkładzie wartości w kolumnie wiodącej: po zbudowaniu statystyk 24248 wierszy IsArchivedbyło fałszywych , a 216 602 wierszy było prawdą .

Ponadto przedmiotem statystyki mówi są (1 / 0,5) = 2 dla różnych wartości IsArchived(1 / 4.149378E-06) ~ = 241000 różne wartości (IsArchived, Mystery)o średniej wielkości rzędu 37 bajtów, a nie do tej samej częstotliwości (IsArchived, Mystery, Id)z 4 dodatkowe bajty na wiersz.

To wszystko dobre informacje ogólnego przeznaczenia, które można łączyć z informacjami statystycznymi o innych kolumnach, aby uzyskać oszacowanie selektywności w zapytaniach z wieloma predykatami (jak wspomniano).

Paul White 9
źródło