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.