Birleştirme ipucu eklediğimde neden SQL Server satır tahminleri değişiyor?


15

Birkaç tablo birleştirir ve oldukça kötü performans gösteren bir sorgu var - satır tahminleri (1000 kez) kapalı ve iç içe döngüler katılmak, birden çok tablo tarama sonuçlanır. Sorgunun şekli oldukça basittir, şuna benzer:

SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id 
WHERE t4.id = some_GUID

Sorgu ile uğraşırken, ben bir birleşimler için bir birleştirme birleştirmek kullanmak için ipucu zaman, çok daha hızlı çalışır fark ettim. Bunu anlayabiliyorum - Birleştirme birleşimi, birleştirilen veriler için daha iyi bir seçenektir, ancak SQL Server yalnızca İç İçe Döngüler'i seçerek bunu tahmin etmez.

Tam olarak anlamadığım şey, bu birleştirme ipucunun neden tüm plan operatörleri için tüm tahminleri değiştirdiğidir? Farklı makaleleri ve kitapları okuyarak, kardinalite tahminlerinin plan oluşturulmadan önce yapıldığını varsaydım, bu yüzden bir ipucu kullanmak tahminleri değiştirmezdi, daha ziyade açıkça SQL Server'a belirli bir fiziksel birleştirme uygulamasını kullanmasını söylerdi.

Ancak gördüğüm şey, Birleştirme ipucunun tüm tahminlerin neredeyse mükemmel olmasına neden olmasıdır. Bu neden oluyor ve sorgu optimize ediciyi ipucu olmadan daha iyi bir tahmin yapmak için yaygın teknikler var - istatistiklerin açıkça buna izin verdiğini düşünüyoruz?

UPD: anonimleştirilmiş yürütme planlarına buradan ulaşabilirsiniz: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?d = 0

TF 3604, 9292 ve 9204 kullanarak her iki sorgu tarafından kullanılan istatistikleri kontrol ettim ve bunlar aynı. Ancak taranan / aranan dizinler sorgular arasında farklılık gösterir.

Bunun yanı sıra, sorguyu çalıştırmayı denedim OPTION (FORCE ORDER)- her birleştirme için HASH MATCH seçerek, birleştirme birleşimini kullanmaktan daha hızlı çalışır.


3
Dış bir birleşim olduğunu fark ettiniz, ancak daha sonra nerede yan tümcesindeki tabloyu kullanıyorsunuz?
James Z

@JamesZ - evet, bunun farkındayım, bununla ilgili bir sorun olduğunu düşünmüyorum.
Alexander Shelemin

9
@AlexSh Bununla ilgili mantıklı / anlamsal bir sorun var, çünkü bu dış birleşiminizi bir iç birleşime değiştiriyor.
Aaron Bertrand

Yanıtlar:


21

Farklı makale ve kitapları okurken kardinalite tahminlerinin plan oluşturulmadan önce yapıldığını varsaydım.

Tam olarak değil. Optimize edici tarafından seçilen ilk birleşme sırasını etkileyen bir başlangıç ​​kardinalite tahmini (basitleştirmeler ve diğer çalışmalardan sonra) elde edilir.

Bununla birlikte, sonraki keşifler (maliyete dayalı optimizasyon sırasında) yeni kardinalite tahminlerinin hesaplanmasına neden olabilir ve çoğu zaman bunu yapabilir. Daha sonraki bu CE'ler aşağı yukarı 'doğru' olabilir. Düşük tahmin sonuçları varsa, optimize edici daha ucuz görünen ancak aslında çok daha uzun süre çalışan bir plan seçebilir.

Genel olarak, anlamsal olarak özdeş alt ağaçlara yönelik kardinalite tahminlerinin aynı sonuçları üreteceğinin garantisi yoktur. Ne de olsa istatistiksel bir süreçtir ve bazı operasyonlar diğerlerinden daha derin CE desteğine sahiptir.

Sizin durumunuzda, başka bir faktör var gibi görünüyor - optimize edici, altındaki alt ağaçta bir satır hedefi belirleyen bir Üst ekler (veya hareket eder) :

Parçayı planla

İzleme bayrağını 4138'i etkinleştirirseniz (2008 R2 veya üzeri sürümlerde), tahminleri beklentilerle daha uyumlu veya belki de optimize edicinin artık iç içe döngüler seçmeyeceğini görebilirsiniz.

Ancak gördüğüm şey, Birleştirme ipucunun tüm tahminlerin neredeyse mükemmel olmasına neden olmasıdır.

Burada bir şans unsuru var. İnsanlar, fiziksel olarak gerçekleştirilmelerini bekledikleri sırayla sorgu veya en azından birleştirme yazma eğilimindedir. Birleştirme ipucu kullanmak FORCE ORDER, ima edilen metinle eşleşecek şekilde birleştirme sırasını sabitler ve kardinalite yeniden tahminine yol açabilecek birçok optimize edici keşif kuralını kapatır.

Bunun yanı sıra, sorguyu çalıştırmayı denedim OPTION (FORCE ORDER)- her birleştirme için HASH MATCH seçerek, birleştirme birleşimini kullanmaktan daha hızlı çalışır.

Bu bir birleştirmeyi ima etmekle aynıdır, ancak fiziksel birleştirme operatörü seçimini kısıtlamaz. Yine, sorgu birleştirme sırasını mantıklı bir şekilde yazdıysanız, makul bir plan almanız muhtemeldir. Tabii ki, optimize edicinin yeteneklerinin çoğunu bu şekilde kaçırırsınız, bu da daha genel durumlarda en iyi sonuçları vermeyebilir.

Muhtemelen FORCE ORDERçok sık kullanmak istemeyeceksiniz, çünkü birleşimlerin sırasını zorlamaktan daha geniş etkileri olan son derece güçlü bir ipucu (yönerge); örneğin, iyileştiricinin kümeleri hareket ettirmesini ve kısmi kümeler eklemesini önler. Bu ipucunu çok istisnai durumlar dışında ve gerçekten uzman tunerler dışında kullanmamanızı tavsiye ederim .

Ayrıntılı bir analiz şu anda sahip olduğumdan daha fazla zaman gerektiriyor ve veritabanının sadece istatistikli bir kopyasına erişim gerektiriyor.


-10

Solu nerede reddediyor
? Neden optimize ediciyi zorlaştırıyorsunuz?
Optimize edici 3 veya daha fazla birleşimde hafızayı koruduğu için savunmaya ve döngü birleşimlerine girme
eğiliminde olacaktır. hala bir gerçeklik
Birden fazla birleştirme ile koşulları,

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
  JOIN t4 
        ON t3.t4_id = t4.id 
       AND t4.id = some_GUID 

Ya da daha da iyisi - bahse girerim, bu ipuçlarınızı veya gücünüzü karşılayacak

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
       AND t3.t4_id = some_GUID

İpuçlarıyla ilgili sorun, belirli bir durumdaki veriler içindir. Temiz bir sorgu yazın ve optimize edicinin işini yapmasına izin verin. Bazı zamanlar doğru şeyi yapmak için daha fazla istatistiğe ihtiyaç duyar, ancak o zaman kilitlenir.

Neden farklı tahminler. Farklı planlar. Optimize ediciye savaşma şansı veren sorgularla başlayın.

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.