Mana yang lebih baik: banyak kondisi bergabung atau banyak kondisi di mana?

13

Saya mencoba membandingkan dua pertanyaan:

Pertanyaan 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 

Pertanyaan 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 

Apakah saya berhak mengatakan bahwa kedua pertanyaan ini memberikan hasil yang sama?

Lebih lanjut, apakah benar mengatakan bahwa permintaan pertama membangun tabel yang lebih besar untuk melakukan WHEREkondisi yang lebih besar ; sedangkan kasus kedua kita memiliki tabel yang dibangun lebih kecil yang WHEREkemudian diterapkan sederhana .

Dengan asumsi hasilnya sama, kueri mana yang lebih disukai? Apakah ada masalah kinerja yang jelas?

Geoff
sumber
3
Tidak, kamu tidak benar mengatakan itu. Itu akan terjadi jika itu adalah INNER JOIN, tetapi dengan LEFT JOINini akan menghasilkan hasil yang berbeda. Pada dasarnya, kondisi yang Anda tambahkan pada WHEREpermintaan kedua Anda mengubah Anda JOINpadaINNER JOIN
Lamak
Ah baiklah. Saya mengikuti apa yang Anda katakan. Jika saya mengedit agar INNER JOINpertanyaan saya tentang kinerja tetap valid?
Geoff
4
Untuk INNER JOINs seharusnya tidak ada perbedaan dalam kinerja. Yang mengatakan, untuk keterbacaan dan ekspresi maksud yang tepat, Anda harus menggunakan kriteria bergabung di ONdan menyaring kriteria di WHERE.
Aaron Bertrand
@ ypercube benar, saya melewatkan kondisi itu.
Lamak

Jawaban:

10

Jika kami menganggap bahwa Anda menggunakan INNER JOINalih-alih LEFT JOIN(yang tampaknya adalah maksud Anda), kedua kueri ini secara fungsional setara. Pengoptimal permintaan akan meninjau dan mengevaluasi kriteria dalam WHEREklausa Anda dan klausa Anda FROMdan mempertimbangkan semua faktor ini ketika membangun rencana kueri untuk mencapai rencana eksekusi yang paling efisien. Jika kita melakukan EXPLAINpada kedua pernyataan, kita mendapatkan hasil yang sama:

Pertanyaan 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

[Hasil] :

| 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 |

Pertanyaan 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

[Hasil] :

| 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 |

Anda dapat meninjau detail lengkapnya dengan tautan berikut. Saya juga membuat contoh SQL 2008 sehingga Anda dapat membandingkan cara kerja dua mesin (yang sama):

Contoh permintaan MySQL

Contoh kueri SQL 2008 (Pastikan Anda 'Lihat Rencana Eksekusi' untuk kedua hasil)

Mike Fal
sumber
Terima kasih atas solusi terperinci Anda. Saya mencoba INNER JOINbukan LEFT JOINdan saya mendapatkan hasil yang sama dalam sepersepuluh waktu. Saya rasa saya tahu mengapa saya mendapatkan output yang sama, tetapi mengapa INNER JOINkinerja yang lebih baik?
Geoff
4
Seperti LEFT JOINgabungan luar, itu tidak dapat membatasi set data di sisi pengembalian penuh set dan akan mencoba untuk mengambil semua baris dari tabel itu (dalam hal ini, TableA). Jika Anda menggunakan INNER JOIN, itu dapat memanfaatkan kriteria itu di kedua tabel dan membatasi set data, sehingga memberikan pengembalian yang lebih cepat.
Mike Fal