Hangisi daha iyi: birçok birleşim koşulu veya birçok nerede koşul?


13

İki sorguyu karşılaştırmaya çalışıyorum:

Sorgu 1:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a
WHERE tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  AND tableA.e=tableB.e 

Sorgu 2:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a AND tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  
WHERE tableA.e=tableB.e 

Bu iki sorgunun aynı sonuçları verdiğini söyleyebilir miyim?

Ayrıca, ilk sorgunun daha büyük bir WHEREkoşul yapmak için daha büyük bir tablo oluşturduğunu söylemek doğru mu? ikinci durumda WHERE, daha sonra basit olanın uygulandığı daha küçük bir tablo oluşturduk .

Sonuçların aynı olduğu varsayılarak hangi sorgu tercih edilmelidir? Açık bir performans sorunu var mı?


3
Hayır, bunu söylemekte haklı değilsin. Bu bir olsaydı olurdu INNER JOIN, ama LEFT JOINbu farklı sonuçlar getirecektir. Temel olarak, WHEREikinci sorgunuza eklediğiniz koşullar JOIN, birINNER JOIN
Lamak

Ah tamam. Söylediklerini takip ediyorum. INNER JOINPerformansla ilgili sorularımı düzenlemek için düzenlersem geçerli olur mu?
Geoff

4
INNER JOIN'ler için performansta hiçbir fark olmamalıdır. Bununla birlikte, okunabilirlik ve niyetin doğru ifadesi için, ve öğesinde ONfiltre ölçütlerinde birleştirme ölçütleri kullanmalısınız WHERE.
Aaron Bertrand

@ ypercube doğru, bu koşulu kaçırdım.
Lamak

Yanıtlar:


10

(Bu sizin niyetiniz gibi görünüyor) INNER JOINyerine kullandığınızı düşünürsek LEFT JOIN, bu iki sorgu işlevsel olarak eşdeğerdir. Sorgu optimize ediciler, en etkili yürütme planına ulaşmak için WHERE, FROMyan tümcenizdeki ve yan tümcenizdeki ölçütleri inceleyecek ve değerlendirecek ve sorgu planları oluştururken tüm bu faktörleri göz önünde bulunduracaktır. Her EXPLAINiki ifadede de bir açıklama yaparsak, aynı sonucu alırız:

Sorgu 1 :

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
WHERE 
  tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
  AND tableA.ColE=tableB.ColE

[Sonuçlar] :

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

Sorgu 2 :

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
  AND tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
WHERE
  tableA.ColE=tableB.ColE

[Sonuçlar] :

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

Aşağıdaki bağlantılarla tüm ayrıntıları inceleyebilirsiniz. İki motorun nasıl çalıştığını da karşılaştırabilmeniz için bir SQL 2008 örneği oluşturdum (aynı):

MySQL sorgu örneği

SQL 2008 sorgu örneği (Her iki sonuç için de 'Yürütme Planını Görüntüle' olduğunuzdan emin olun)


Ayrıntılı çözümünüz için teşekkür ederiz. Bunun INNER JOINyerine denedim LEFT JOINve aynı çıktıyı onda onda alıyorum. Sanırım neden aynı çıktıyı aldığımı biliyorum, ama neden INNER JOINdaha iyi bir performans elde edesin ki?
Geoff

4
LEFT JOINDış birleşim olduğu gibi , kümenin tam dönüş tarafındaki veri kümesini kısıtlayamaz ve bu tablodan tüm satırları almaya çalışır (bu durumda, TableA). Eğer kullanırsanız INNER JOIN, bu yüzden daha hızlı bir geri dönüş sağlayacağı veri seti hem tablolarda bu kriterleri kaldıraç ve kısıtlayabilir.
Mike Fal
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.