Adım içi istatistik değeri için> = ve> için Kardinalite Tahmini


9

SQL Server 'daha büyük' ​​ve 'eşittir' eşit nerede SQL Server 2014 yan tümceleri için tahmin etmeye çalıştığını anlamaya çalışıyorum.

Sanırım adımı vurduğunda kardinalite tahminini anlıyorum, örneğin

    select * from charge where charge_dt >= '1999-10-13 10:47:38.550'

Kardinalite tahmini 6672'dir ve 32 (EQ_ROWS) + 6624 (RANGE_ROWS) + 16 (EQ_ROWS) = 6672 (aşağıdaki ekran görüntüsünde histogram) olarak kolayca hesaplanabilir

resim açıklamasını buraya girin

Ama yaptığımda

    select * from charge where charge_dt >= '1999-10-13 10:48:38.550' 

(zamanı 10:48'e çıkardı, bu yüzden bir adım değil)

tahmin 4844.13'tür.

Bu nasıl hesaplanır?

Yanıtlar:


9

Tek zorluk, sorgu belirleme aralığı tarafından kısmen kapsanan histogram adımlarının nasıl ele alınacağına karar vermektir . Yüklem aralığının kapsadığı tüm histogram adımları, soruda belirtildiği gibi önemsizdir.

Eski Kardinalite Tahmincisi

F = sorgu yükleminin kapsadığı adım aralığının fraksiyonu (0 ile 1 arasında).

Temel fikir, Fadım içi farklı değerlerin kaçının yüklem tarafından kapsanacağını belirlemek için (doğrusal enterpolasyon) kullanmaktır . Bu sonucu farklı değer başına ortalama satır sayısıyla çarpmak (tekdüzelik varsayarak) ve adım eşit satırları eklemek kardinalite tahmini verir:

Kardinalite = EQ_ROWS + (AVG_RANGE_ROWS * F * DISTINCT_RANGE_ROWS)

Aynı formül eski CE için >ve >=eski CE için kullanılır .

Yeni Kardinalite Tahmincisi

Yeni CE, önceki algoritmayı >ve arasında ayrım yapmak için biraz değiştirir >=.

Alarak >birinci, formül:

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

Çünkü >=:

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

+ 1Karşılaştırma eşitliği ile ilgili olduğunda, bir maç (içerme varsayımı) varsayılır yansıtmaktadır.

Soru örneğinde Fşu şekilde hesaplanabilir:

DECLARE 
    @Q datetime = '1999-10-13T10:48:38.550',
    @K1 datetime = '1999-10-13T10:47:38.550',
    @K2 datetime = '1999-10-13T10:51:19.317';

DECLARE
    @QR float = DATEDIFF(MILLISECOND, @Q, @K2), -- predicate range
    @SR float = DATEDIFF(MILLISECOND, @K1, @K2) -- whole step range

SELECT
    F = @QR / @SR;

Sonuç 0.728219019233034'tür . Bunu, >=bilinen diğer değerlerle formüle eklemek :

Kardinalite = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
            = 16 + (16.1956 * ((0.728219019233034 * (409-1)) + 1))
            = 16 + (16.1956 * ((0.728219019233034 * 408) + 1))
            = 16 + (16.1956 * (297.113359847077872 + 1))
            = 16 + (16.1956 * 298.113359847077872)
            = 16 + 4828.1247307393343837632
            = 4844.1247307393343837632
            = 4844.12473073933 (hassasiyeti yüzdürmek için)

Bu sonuç, soruda gösterilen 4844.13 tahmini ile uyumludur.

Eski CE'yi kullanan aynı sorgu (örneğin, izleme bayrağı 9481'i kullanarak) aşağıdakilere ilişkin bir tahmin üretmelidir:

Kardinalite = EQ_ROWS + (AVG_RANGE_ROWS * F * DISTINCT_RANGE_ROWS)
            = 16 + (16.1956 * 0.728219019233034 * 409)
            = 16 + 4823.72307468722
            = 4839.72307468722

Tahmin , eski CE için >ve >=eski CE için aynı olacaktır .


4

Filtre "büyük" veya "küçük" olduğunda, satırları tahmin etme formülü biraz saçma olur, ancak bu, ulaşabileceğiniz bir sayıdır.

Sayılar

Adım 193'ü kullanarak, ilgili sayılar şunlardır:

RANGE_ROWS = 6624

EQ_ROWS = 16

AVG_RANGE_ROWS = 16.1956

Önceki adımdan RANGE_HI_KEY = 1999-10-13 10: 47: 38.550

Geçerli adımdan RANGE_HI_KEY = 1999-10-13 10: 51: 19.317

WHERE maddesinden değer = 1999-10-13 10: 48: 38.550

Formül

1) İki aralıklı hi tuşu arasındaki ms'yi bulun

SELECT DATEDIFF (ms, '1999-10-13 10:47:38.550', '1999-10-13 10:51:19.317')

Sonuç 220767 ms'dir.

2) Satır sayısını ayarlayın

Milisaniye başına satır bulmamız gerekiyor, ancak yapmadan önce AVG_RANGE_ROWS değerini RANGE_ROWS'tan çıkarmamız gerekiyor:

6624-16.1956 = 6607.8044 satır

3) Ayarlanan satır sayısı ile ms başına satır sayısını hesaplayın:

6607.8044 satır / 220767 ms = ms başına .0299311 satır

4) WHERE yan tümcesindeki değer ile geçerli RANGE_HI_KEY adımı arasındaki ms'yi hesaplayın

SELECT DATEDIFF (ms, '1999-10-13 10:48:38.550', '1999-10-13 10:51:19.317')

Bu bize 160767 ms verir.

5) Bu adımdaki satırları saniyedeki satır sayısına göre hesaplayın:

.0299311 satır / ms * 160767 ms = 4811.9332 satır

6) AVG_RANGE_ROWS'u daha önce nasıl çıkardığımızı hatırlıyor musunuz? Onları geri ekleme zamanı. Artık saniyedeki satır sayısı ile ilgili sayıları hesapladığımızdan EQ_ROWS'u da güvenle ekleyebiliriz:

4811.9332 + 16.1956 + 16 = 4844.1288

Sonuç olarak, bu bizim 4844.13 tahminimizdir.

Formülü test etme

AVG_RANGE_ROWS'un neden ms başına satır hesaplanmadan önce çıkarıldığına dair herhangi bir makale veya blog yayını bulamadım. Ben idi anlamıyla - onlar tahmini, ama sadece son milisaniye değerleriyle, onaylamak mümkün.

WideWorldImporters veritabanını kullanarak, bazı artımlı testler yaptım ve satır tahminlerindeki azalmanın adımın sonuna kadar doğrusal olduğunu gördüm, burada 1x AVG_RANGE_ROWS aniden hesaplandı.

İşte benim örnek sorgu:

SELECT PickingCompletedWhen
FROM Sales.Orders
WHERE PickingCompletedWhen >= '2016-05-24 11:00:01.000000'

PickingCompletedWist istatistiklerini güncelledikten sonra histogramı aldım:

DBCC SHOW_STATISTICS([sales.orders], '_WA_Sys_0000000E_44CA3770')

_WA_Sys_0000000E_44CA3770 için histogram (son 3 adım)

RANGE_HI_KEY'e yaklaştıkça tahmini satırların nasıl azaldığını görmek için adım boyunca örnekleri topladım. Düşüş doğrusaldır, ancak AVG_RANGE_ROWS değerine eşit sayıda satır sadece trendin bir parçası değil gibi davranır ... siz RANGE_HI_KEY'e çarpana ve aniden tahsil edilmemiş borç gibi düşene kadar. Bunu örnek verilerde, özellikle grafikte görebilirsiniz.

resim açıklamasını buraya girin

Biz RANGE_HI_KEY ve sonra son AVG_RANGE_ROWS yığın aniden çıkarılır BOOM vurmak kadar satırlarda sürekli düşüş dikkat edin. Bir grafiği görmek de kolaydır.

resim açıklamasını buraya girin

Özetle, AVG_RANGE_ROWS'un garip muamelesi, satır tahminlerini hesaplamayı daha karmaşık hale getirir, ancak CE'nin ne yaptığını her zaman uzlaştırabilirsiniz.

Üstel Geri Çekilme ne olacak?

Üstel Geri Çekme, yeni (SQL Server 2014'ten itibaren) Kardinalite Tahmincisi'nin birden çok tek sütunlu istatistik kullanırken daha iyi tahminler elde etmek için kullandığı yöntemdir. Bu soru yaklaşık tek sütunlu bir istatistik olduğundan EB formülünü içermez.

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.