Kısmen kapsama aralığının tahmin tahmini


13

Şu anda SQL Server'ın histogram adımını kısmen kaplayan aralıkların kardinalliğini nasıl değerlendirdiğini anlamaya çalışıyorum.

İnternette, adım içi ve istatistik içi kardinalite tahmininde benzer bir soruya rastladım ve Paul White buna oldukça ilginç bir cevap verdi.

Paul'un cevabına göre,> = ve> tahminleri için kardinalliği tahmin etmeye yönelik formüller (bu durumda, sadece en az 120 olan Kardinalite tahmin modeliyle ilgileniyorum) aşağıdaki gibidir:

İçin:

Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))

> = İçin:

Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))

Bu formüllerin uygulanmasını AdventureWorks2014 veritabanının [TransactionHistory] tablosunda TransactionDate sütununu ve '20140614' ile '20140618' arasındaki datetime aralığını kullanarak aralık yüklemine dayalı olarak test ettim.

Bu aralığın histogram adımı için istatistikler aşağıdaki gibidir:

Histogram

Formüle göre, aşağıdaki sorgu için kardinaliteyi hesapladım:

SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'

Hesaplama aşağıdaki kod kullanılarak yapıldı:

  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]

Hesapladıktan sonra, aşağıdaki sonuçları aldım:

resim açıklamasını buraya girin

Formüle göre, 150.5 çıktı, ancak optimize edici yüklemi 225.75 satır olarak tahmin ediyor ve yüklemin üst kenarlığını '20140617' olarak değiştirirseniz, optimize edici zaten 250.833 satırı değerlendirir, yalnızca 200.6666 satır.

Lütfen söyle, Kardinalite Tahmincisi bu durumda nasıl değerlendiriyor, belki de alıntılanan formülleri anladığımda bir yerde hata yaptım?


Sql server 2014 12.0.5 SP2
Павел Ковалёв

Yanıtlar:


12

SQL Server, farklı durumlarda farklı hesaplamalar kullanır. Örneğiniz bağlı Soru ve Cevaplardan farklıdır çünkü aralığınız tamamen bir adımda yer almaktadır; adım sınırını aşmaz. Aynı zamanda bir değil iki uçlu bir aralıktır. Yazmak ve BETWEENile iki ayrı tahmine yazmakla aynıdır .>=<=

Tek bir adımda iki sınırlı aralık

Formül, beklenen farklı değerlerin sayısı için adımda doğrusal enterpolasyon gerçekleştirmek üzere modifiye edilir ve şimdi bir yerine iki aralık uç noktasının belirtildiğini (ve histogram adımında var olduğu varsayılır) yansıtır.

Soruda verilen histogram adımlarını kullanarak:

soru histogramı adımları

İle sorgu BETWEEN '20140615' AND '20140616'için hesaplama:

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);

... 225.75 veriyor . Değişen @Q2gelen '20140616'etmek '20140617'bir sonucu verir 250.833 .

Her iki sonuç da soruda verilenlerle eşleşir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.