SQL Server'ın optimize edici, birleştirilmiş tablodaki satır sayısını nasıl tahmin eder?


13

Bu sorguyu AdventureWorks2012 veritabanında çalıştırıyorum:

SELECT 
    s.SalesOrderID,
    d.CarrierTrackingNumber,
    d.ProductID,
    d.OrderQty
FROM Sales.SalesOrderHeader s 
JOIN Sales.SalesOrderDetail d 
    ON s.SalesOrderID = d.SalesOrderID
WHERE s.CustomerID = 11077

Tahmini yürütme planına bakarsam aşağıdakileri görürüm:

resim açıklamasını buraya girin

İlk dizin araması (sağ üstte) IX_SalesOrderHeader_CustomerID dizinini kullanıyor ve 11077 değişmez değerini arıyor. Tahmini 2.6192 satır.

resim açıklamasını buraya girin

Kullanmak ise DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM, değerin 11077, iki örnek şifreler 11019 ve 11091 arasında olduğunu göstermektedir.

resim açıklamasını buraya girin

11019 ve 11091 arasındaki farklı satırların ortalama sayısı 2.619718'dir veya indeks arayışı için gösterilen tahmini satırların değeri olan 2.61972'ye yuvarlanır.

Anlamadığım bölüm, SalesOrderDetail tablosuna karşı kümelenmiş dizin araması için tahmini satır sayısıdır.

resim açıklamasını buraya girin

Eğer koşarsam DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'):

resim açıklamasını buraya girin

Yani (katıldığım) SalesOrderID yoğunluğu 3.178134E-05. Bu, 1 / 3.178134E-05 (31465) öğesinin SalesOrderDetail tablosundaki benzersiz SalesOrderID değerlerinin sayısına eşit olduğu anlamına gelir.

SalesOrderDetail'ta 31465 benzersiz SalesOrderID varsa, eşit bir dağıtımla, SalesOrderID başına ortalama satır sayısı 121317'dir (toplam satır sayısı) 31465'e bölünür. Ortalama 3.85561

Dolayısıyla, döngüden geçirilecek tahmini satır sayısı 2.61972 ise ve 3.85561'de döndürülecek ortalama ise, tahmini satır sayısının 2.61972 * 3.85561 = 10.10062 olacağını düşünürüm.

Ancak tahmini satır sayısı 11.4867'dir.

İkinci tahmine ilişkin anlayışımın yanlış olduğunu düşünüyorum ve farklı sayılar bunu gösteriyor gibi görünüyor. Neyi kaçırıyorum?

Yanıtlar:


20

İkinci tahmine ilişkin anlayışımın yanlış olduğunu düşünüyorum ve farklı sayılar bunu gösteriyor gibi görünüyor. Neyi kaçırıyorum?

SQL Server 2012 kardinalite tahmincisini kullanarak birleştirme seçiciliği, iç içe döngülerin iç tarafındaki tahmini satır sayısını birleştirir, tersi yönde değil.

11,4867 sayıdır türetilmiş bilgisayarlı tahmini önem düzeyi bölerek (SHOWPLAN görüntülemek için) adım sayısı (2,61972) ile çıkış (30,0919) birbirine birleştirilir. Tek kesinlikli kayar nokta aritmetiği kullanılarak sonuç 11.4867'dir .

Gerçekten bu kadar basit. (Mantıksal) birleştirme seçiciliğinin fiziksel birleştirme operatörü seçiminden bağımsız olduğunu unutmayın. Birleştirme işleminin sonunda Yuvalanmış Döngüler, Karma veya Birleştirme Birleştirme fiziksel işleci kullanılarak gerçekleştirilmesi aynı kalır.

SQL Server 2012 ve önceki sürümlerde birleştirme seçiciliği (bir bütün olarak), SalesOrderIDher bir tablodaki histogramlar kullanılarak hesaplanır (her bir histogram adımı için, gerektiğinde doğrusal enterpolasyon kullanılarak adım sınır hizalamasından sonra hesaplanır). SalesOrderIDİle ilişkili histogram SalesOrderHeadertablo aynı zamanda bağımsız bir ölçekleme etkisinden arındırılmış olan CustomerIDfiltre.

Bu, soruda önerilen alternatif hesaplamayla temelde 'yanlış' bir şey olduğu anlamına gelmez; sadece farklı bir dizi varsayım yapar. Belirli bir mantıksal işlem dizisi için tahminleri hesaplamanın veya birleştirmenin her zaman farklı yolları olacaktır. Aynı verilere uygulanan farklı istatistiksel yöntemlerin aynı cevapları üreteceği veya bir yöntemin her zaman diğerinden daha üstün olacağına dair genel bir garanti yoktur. Farklı istatistiksel yöntemlerin uygulanmasından kaynaklanan tutarsızlıklar, nadiren fark edilmelerine rağmen, tek bir nihai uygulama planında bile ortaya çıkabilir.

Bir yan not olarak, SQL Server 2014 kardinalite tahmincisi bağımsız filtreye göre ayarlanmış histogram bilgisini ( "kaba hizalama" ) birleştirmek için farklı bir yaklaşım benimser ve bu da bu sorgu için 10.1006 satırlık farklı bir son tahminle sonuçlanır :

Plan for computation:

  CSelCalcExpressionComparedToExpression
  (QCOL: [s].SalesOrderID x_cmpEq QCOL: [d].SalesOrderID)

Loaded histogram for column QCOL: [s].SalesOrderID from stats with id 1
Loaded histogram for column QCOL: [d].SalesOrderID from stats with id 1

Stats collection generated: 

  CStCollJoin(ID=4, **CARD=10.1006** x_jtInner)
      CStCollFilter(ID=3, CARD=2.61972)
          CStCollBaseTable(ID=1, CARD=31465 TBL: Sales.SalesOrderHeader AS TBL: s)
      CStCollBaseTable(ID=2, CARD=121317 TBL: Sales.SalesOrderDetail AS TBL: d)

Ayrıntılı akıl yürütme farklı olsa da, bu sorudaki hesaplama ile aynı sonuç olur (yani varsayılan bir iç içe döngüler uygulamasına dayanmaz).

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.