JOIN yan tümcesinde yapı KULLANIMI bazı durumlarda optimizasyon engelleri oluşturabilir mi?


35

Sorgu maddesindekiUSING yapının (yerine ON) belirli durumlarda optimizasyon engelleri getirebileceği dikkatimi çekti .FROMSELECT

Bu anahtar kelimeyi kastediyorum:

SEÇ *
Bir
B KULLANIMI KATILIN (a_id)

Sadece daha karmaşık durumlarda.

Bağlam: Bu yorumu için bu soruya .

Bunu çok kullanıyorum ve şimdiye kadar hiçbir şey fark etmedim. Daha fazla bilgi için etkiyi ya da herhangi bir bağlantıyı gösteren bir test vakasıyla ilgileneceğim . Arama çabalarım boşaldı.

Mükemmel bir cevap USING (a_id), alternatif birleştirme yan tümcesine kıyasla daha düşük performansla gösteren bir test durumu olacaktır ON a.a_id = b.a_id- eğer gerçekten olabilirse.


2
@kgrittn: Genelde şu ana kadar beklediğim bu: USINGbiraz daha hızlı - sonuç matrisinde daha az bir sütunla sonuçlandığı için biraz daha hızlı . Bulgularınız 2005 ve 2008 yıllarına kadar uzanıyor. Şimdilik herhangi bir sorunun çözüldüğünü varsayıyorum. Ancak , olası bir sınırlama görebiliyorum: Ortaya çıkan birleştirme kolonu bir ortak ürün olduğu için sırasıyla birleştirme işleminin uygulanmasıUSING gerekebilir . Böylece JOIN'lerin yeniden sıralanmasında potansiyel olarak sınırlayıcı seçenekler.
Erwin Brandstetter

1
Beni bu kadar sık ​​kullanmamaya bırakmakla bir ilgisi olabilecek bu konuyu buldum, çünkü bir birleşimde KULLANMA koşulu olan bir VAR döküm / geri yükleme ile ilgili sorunlara neden olabilir: archives.postgresql.org/pgsql- bugs / 2011-06 / msg00030.php Hala, geçici çözümün ON kullanacağı USING performans sorunlarıyla ilgili başka bir konu olduğunu merak ediyorum, sanırım buluyorum. Görüşlerin dışında kullanmak muhtemelen güvenlidir ve sadece bir sorgu yavaşsa teşhis adımı olarak denemeyi unutmayın.
kgrittn

1
"Kullanımı" kodu biraz okunabilir kılıyor gibi görünüyor, ancak sanırım iki alanın da aynı ada ihtiyacı var. Kullanmanın "açık" ten daha iyi bir performansa sahip olacağını sanmıyorum, çünkü DB yine de eşleşmeye ihtiyaç duyuyor, seçim yapmak bir katılımla aynı performansa sahip (sanki yanlış olursam beni düzeltmek gibi). Aradaki fark, Join'in daha temiz ve bakımı kolaydır.
jcho360

2
@ HLGEM: Bu sadece sembolik bir isim ve benim örneğimde olduğu gibi sadece iki tabloyla karışıklığa yer yok. Yine de soruyu değiştirdim. Talihsiz idolarak sütun adı kullanılmasını teşvik etmek istemem .
Erwin Brandstetter

2
@ ChristianiaWesterbeek: Ben katılmıyorum. "Go-to place" Postgres cevap in-derinlikleri için ise (hala) posta.
SO'da

Yanıtlar:


12

Erwin: Sert bir düzene neden olan USING'in, en iyi planların göz ardı edileceği birçok yeni durum yaratabileceği fikrine katılıyorum. Geçenlerde sorgusunda böyle bir şey olan birine yardım ettim:

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

Bu durumda, bu birleştirme bloklarının en kötüsü, yaklaşık 200k satır boyunca iç içe geçen bir halkanın birleşmesine neden oldu (yaklaşık 20k kez) ve tuşlar indekslere itilemediğinden, sıralı bir taramaydı. Bu, genel sorgunun basamaklı plan değişiklikleri nedeniyle çalışması yaklaşık 3 saat sürdüğü anlamına geliyordu. Sol birleştirmeyi dağıtarak, tuşlar aşağı itilebilir ve sorgu birkaç saniye içinde çalıştırılabilir. Elbette bu tam olarak eşdeğer değildir, bu nedenle planlamacının onlara eşdeğer olarak muamele edememesinin nedeni, bu planın bir karma birleşimi olarak ortaya çıkması ve sonra acılı bir şekilde yavaş olan iç içe bir döngü yapmasıdır.

Birleşmeleri kesin bir düzende katı bir şekilde geçmeye zorladığınız zaman, anahtar filtre bilgilerinin henüz planın uygulanmasında bulunamadığı durumları ve daha sonra hızlı bir indeks taraması / hash birleştirmesinde daha sonra ne yapılabileceğini ortaya koyarsınız. Yuvalanmış bir döngü / sıralı taramada çok daha yavaş yapılması gerekebilir ve bu yüzden yukarıdaki parça hemen eşdeğer olmasa da aynı sorunu gösterir.

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.