Oszacowanie normalności częściowo pokrywających predykatów zasięgu


13

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:

Histogram

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:

wprowadź opis zdjęcia tutaj

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ł?


Serwer SQL 2014 12.0.5 z dodatkiem SP2
Павел Ковалёв

Odpowiedzi:


12

SQL Server używa różnych obliczeń w różnych sytuacjach. Twój przykład różni się od powiązanych pytań i odpowiedzi, ponieważ twój zakres jest całkowicie zawarty w jednym kroku; nie przekracza granicy kroku. Jest to również przedział z dwoma końcami zamiast jednego. Pisanie BETWEENjest tym samym, co pisanie dwóch osobnych predykatów za pomocą >=i <=.

Interwał z dwiema granicami w ramach jednego kroku

Formuła jest modyfikowana w celu wykonania interpolacji liniowej w ramach kroku dla oczekiwanej liczby różnych wartości i odzwierciedla to, że teraz określono dwa punkty końcowe zakresu (i zakłada się, że istnieją w kroku histogramu), a nie jeden.

Używając kroków histogramu podanych w pytaniu:

zadaj kroki histogramu

W przypadku zapytania z BETWEEN '20140615' AND '20140616'obliczeniem jest:

DECLARE
    @Q1 float = CONVERT(float, CONVERT(datetime, '2014-06-15')),
    @Q2 float = CONVERT(float, CONVERT(datetime, '2014-06-16')),
    @K1 float = CONVERT(float, CONVERT(datetime, '2014-06-14')),
    @K2 float = CONVERT(float, CONVERT(datetime, '2014-06-18')),
    @RANGE_ROWS float = 301,
    @DISTINCT_RANGE_ROWS float = 3;

DECLARE
    @S1 float = (@Q1 - @K1) / (@K2 - @K1),
    @S2 float = (@Q2 - @K1) / (@K2 - @K1);

DECLARE
    @F float = @S2 - @S1;

DECLARE
    @AVG_RANGE_ROWS float = @RANGE_ROWS / @DISTINCT_RANGE_ROWS;

SELECT
    @AVG_RANGE_ROWS * ((@F * (@DISTINCT_RANGE_ROWS - 2)) + 2);

... dając 225.75 . Zmiana @Q2z '20140616'na '20140617'daje wynik 250,833 .

Oba wyniki są zgodne z podanymi w pytaniu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.