W tej chwili próbuję dowiedzieć się, w jaki sposób SQL Server ocenia liczebność predykatów zakresu, które częściowo pokrywają krok histogramu.
W Internecie, przy szacowaniu liczności liczebności dla i statystyki dla kroku w kroku , natrafiłem na podobne pytanie i Paul White udzielił na to dość interesującej odpowiedzi.
Zgodnie z odpowiedzią Paula wzory na oszacowanie liczności dla predykatów> = i> (w tym przypadku interesuje mnie tylko model oszacowania liczności co najmniej 120) są następujące:
Dla>:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))
Dla> =:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
Testowałem zastosowanie tych formuł w tabeli [Production]. [TransactionHistory] w bazie danych AdventureWorks2014 w oparciu o predykat zakresu przy użyciu kolumny TransactionDate i zakresu datetime od „20140614” do „20140618”.
Statystyki dla kroku histogramu tego zakresu są następujące:
Zgodnie ze wzorem obliczyłem liczność dla następującego zapytania:
SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'
Obliczenia przeprowadzono przy użyciu następującego kodu:
DECLARE @predStart DATETIME = '20140615 00:00:00.000'
DECLARE @predEnd DATETIME = '20140616 00:00:00.000'
DECLARE @stepStart DATETIME = '20140614 00:00:00.000'
DECLARE @stepEnd DATETIME = '20140618 00:00:00.000'
DECLARE @predRange FLOAT = DATEDIFF(ms, @predStart, @predEnd)
DECLARE @stepRange FLOAT = DATEDIFF(ms, @stepStart, @stepEnd)
DECLARE @F FLOAT = @predRange / @stepRange;
DECLARE @avg_range_rows FLOAT = 100.3333
DECLARE @distinct_range_rows INT = 3
DECLARE @EQ_ROWS INT = 0
SELECT @F AS 'F'
--for new cardinality estimator
SELECT @EQ_ROWS + @avg_range_rows * (@F * (@distinct_range_rows - 1) + 1) AS [new_card]
Po obliczeniu otrzymałem następujące wyniki:
Zgodnie ze wzorem okazało się, że 150,5, ale optymalizator szacuje predykat na 225.75 wierszy, a jeśli zmienisz górną granicę predykatu na „20140617”, optymalizator oceni już 250.833 wierszy, przy użyciu formuły otrzymamy tylko 200,6666 wierszy.
Proszę, powiedz mi, jak ocenia Cardinality Estimator w tym przypadku, może popełniłem błąd w moim rozumieniu cytowanych formuł?