Aktualziacja statystyk w SQL Server

O Sql Statistics pisałem już tutaj.
Wiemy, że dzięki takim statystykom dobierane są indeksy oraz plany wykonania. Na przykład jeśli zagęszczenie danych jest bardzo niskie, wtedy nawet warto zrezygnować z indeksów.

Utrzymanie statystyk nie jest łatwym zadaniem. Generalnie SQL Server jest odpowiedzialny za ich przeliczanie. Oczywiście przeliczanie od nowa statystyk za każdym razem, gdy dane są zmieniane, byłoby zbyt czasochłonne. Z tego wynika fakt, że istnieje ryzyko, że statystyki nie odzwierciedlają dokładnie danych.  SQL Server aktualizuje je w następujący sposób:

  1. Gdy nie ma żadnych danych, wtedy przeliczane są one w momencie dodania pierwszego wiersza.
  2.  Gdy jest mniej niż 500 wierszy, wtedy przeliczane są one w momencie osiągnięcia progu 500.
  3.  Gdy jest więcej niż 500 wierszy, każda zmiana 20% powoduje ponowne przeliczenie.

Jeśli mamy kilka milionów danych, przy odrobinie pecha, może zdarzyć się, że mniej niż 20% danych zostanie zmodyfikowanych, ale w taki sposób, że zaburzają one aktualnie wyliczoną dystrybucję danych.

W dowolnym momencie możemy sprawdzić, kiedy ostatnio statystyki były przeliczanie. Wystarczy użyć następującej komendy:

DBCC SHOW_STATISTICS('dbo.Articles',PRICE_INDEX)

W wyniku dostaniemy m.in. kolumnę Updated:

Można również ręcznie zaktualizować statystyki za pomocą Update Statistics:

UPDATE STATISTICS Sales.SalesOrderDetail

Możliwe jest również przeliczenie wszystkich statystyk w bazie:

EXEC sp_updatestats

Ostatnio pisałem o fragmentacji indeksów oraz potrzebie ich przebudowania. Dobrą wiadomością jest fakt, że gdy przebudowujemy indeks, również statystyki są przeliczanie. Nie ma zatem potrzeby wykonywania tych dwóch operacji jednocześnie.

Niestety nie ma łatwego sposobu na sprawdzenie, czy należy przebudować statystyki. Zwykle nie ma takiej potrzeby, ale czasami dane są modyfikowane w tabelach w taki sposób, że potrzebna jest ingerencja. Objawia się to wtedy źle dobranymi planami wykonania.

Leave a Reply

Your email address will not be published.