Birleştirme sırası SQL'de önemli mi?


189

Performansı göz ardı ederek, aşağıdaki A ve B sorgusundan aynı sonucu alır mıyım? C ve D'ye ne dersiniz?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

11
Nedir <blahblah>? A'dan B'ye ve A'dan C'ye mi katılıyor, yoksa A'dan B'ye ve B'den C'ye mi katılıyor?
beny23

2
Merhaba Beny, sorumdaki kod bir soyutlama. A'dan B'ye veya A'dan C'ye katılmakla ilgilenmiyorum, sadece bu gibi sözdiziminin aynı sonuçları sağlayacağını bilmek istiyorum.
Sadece bir öğrenci

Yanıtlar:


225

İçin INNERkatılır, hayır, sipariş önemli değildir. Sorgular sürece adresinin seçer değiştikçe, aynı sonuçları getirecektir SELECT *için SELECT a.*, b.*, c.*.


İçin ( LEFT, RIGHTya FULL) OUTER, evet, sipariş konularda birleşimler - ve ( güncellenmiş ) işler çok daha karmaşıktır.

Birincisi, dış birleşimler değişmeli değildir, bu yüzden a LEFT JOIN baynı değildirb LEFT JOIN a

Dış birleşimler de birleştirici değildir, bu nedenle her iki (değişebilirlik ve ilişkilendirilebilirlik) özellikleri içeren örneklerinizde:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

şuna eşittir :

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

fakat:

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

şuna eşdeğer değildir :

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id

Bir başka (umarım daha basit) ilişkilendirilebilirlik örneği. Bunu şöyle düşünün (a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

Bu eşdeğerdir için a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition

sadece "güzel" ONkoşullarımız olduğu için. Hem ON b.ab_id = a.ab_idve c.bc_id = b.bc_ideşitlik denetler ve içermeyen NULLkarşılaştırmalar.

Hatta gibi diğer operatörleri ile şartları veya daha karmaşık olanlar olabilir: ON a.x <= b.xya ON a.x = 7ya ON a.x LIKE b.xya ON (a.x, a.y) = (b.x, b.y)ve iki sorgular hala eşdeğer olacaktır.

Bununla birlikte, bunlardan herhangi biri IS NULLveya null'larla ilgili bir işlev COALESCE(), örneğin koşul varsa b.ab_id IS NULL, iki sorgu eşdeğer olmazsa.


3
Herhangi bir yüklemin, bir tablodaki tüm sütunların NULL olduğu bir satır tarafından tatmin edilemediği sürece dış birleştirmenin birleştirici olduğunu söylemek daha doğrudur, tahminler IS NULL içermediği sürece ilişkisel olduğunu söylemek 'null'larla ilgili bir işlev'. Birisi, eski açıklamayı tatmin eden ancak sonuncusunu karşılamayan bir yüklemi kolayca hayal edebilir a.somecol > 0 OR b.someothercol > 0; ilişkilendirilebilirlik bu durum için başarısız olabilir.
Mark Amery

Ancak evet, yüklemin burada açıkladığım koşullardan herhangi birini karşılamadığı sürece OUTER JOIN'in birleştirici olduğunu söylemek teknik olarak doğru olduğunu düşünüyorum: stackoverflow.com/questions/20022196/… (ilki aynı zamanda ilişkisini de bozuyor) INNER JOIN'ler için, ancak kırılmaya o kadar ucuz ve bariz bir yaklaşımdır ki, belki de bahsetmeye değmez.) Ayrıca, en yaygın JOIN - yabancı bir tuşa katılmak - bu koşullardan herhangi birini karşılamadığını belirtmek gerekir. ve böylece hoş ve çağrışımsaldır.
Mark Amery

1
@MarkAmery Teşekkür ederim, cümlelerimi bu noktada yapılandırmakta zorlanıyordum (ve bu cevabınızı zaten iptal ettim;)
ypercubeᵀᴹ

ypercube i INNER JOINve bir var LEFT JOIN. Öncelikle sorgu Filtertabanındaki kayıtlar INNER JOINsonra da kayıtlar LEFT JOINiçin geçerli olacak Filteredmı?
Muhammad Babar

Aslında, her türlü katılmak olan SQL standardında belirtilen ve ilişkilendirilebilirlik matematiksel tanımlara göre olarak, ilişkisel, ama onlar yok görünen parantez yeniden düzenleyerek hareketli gerektirdiğinden ilişkisel ONmaddesini (yani "spesifikasyonu katıl") yeni bir konuma . Bu sadece sözdizimidir. İlişkisel cebir gösterimini (birleştirme belirtiminin birleştirme işlecinin altına yerleştirildiği yerde) kullanırsanız, ilişkilendirme daha belirgin hale gelir. Argümanınız sadece dış birleşmelerin değişmeli olmadığını gösteriyor , bu doğru
Lukas Eder

4

düzenli birleşme için değil. TableA join TableBile aynı yürütme planını oluşturur TableB join TableA(böylece C ve D örnekleriniz aynı olur)

sol ve sağ birleşimler için. TableA left Join TableBfarklı TableB left Join TableA, ama aynıTableB right Join TableA


4
Bu sadece değişebilirliği ele alır, ancak sorudaki örnekler askerin ilişkililikle ilgilendiğini göstermektedir. ypercube'nin cevabı her ikisine de hitap ediyor.
Mark Amery

2

B'ye katılmadan önce B'den bir alanda C'ye katılmayı denerseniz, yani:

SELECT A.x, A.y, A.z FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN b
       on A.x = B.x

sorgunuz başarısız olur, bu nedenle sipariş önemlidir.


Evet bu doğru, doğru cevap değiştirilmelidir.
Nir Pengas

-2

Oracle optimizer , iç birleşim için birleşim tablolarını seçer. Optimizer, tabloların birleşme sırasını yalnızca basit FROM yan tümcelerinde seçer. U kendi web sitesinde oracle belgelerini kontrol edebilirsiniz. Ve sol, sağ dış birleşim için en çok oy verilen cevap doğrudur. Optimize edici, her bir tablo için en uygun birleştirme sırasını ve en uygun dizini seçer. Birleştirme sırası, hangi dizinin en iyi seçim olduğunu etkileyebilir. Optimize edici, bir iç tabloysa, bir tablo için erişim yolu olarak bir dizin seçebilir, ancak dış tablo ise (ve başka nitelik yoksa) seçemez.

Optimize edici, tabloların birleştirme sırasını yalnızca basit FROM yan tümcelerinde seçer. JOIN anahtar sözcüğünü kullanan çoğu birleşimler basit birleşimlere düzleştirilir, bu nedenle optimize edici birleştirme sırasını seçer.

Optimize edici, dış birleşimler için birleştirme sırasını seçmez; ifadede belirtilen sırayı kullanır.

Bir birleştirme siparişi seçerken, optimize edici şunları göz önünde bulundurur: Her tablonun boyutu Her bir tablodaki dizinler Bir tablodaki bir dizinin belirli bir birleşme düzeninde yararlı olup olmadığı Her bir tablodaki her tablo için taranacak satır ve sayfa sayısı siparişe katıl

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.