Apakah ada perbedaan (kinerja, praktik terbaik, dll ...) antara menempatkan suatu kondisi dalam klausa JOIN vs klausa WHERE?
Sebagai contoh...
-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'
-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'
Yang mana yang Anda sukai (dan mungkin mengapa)?
sql
performance
Steve Dignan
sumber
sumber
FROM Orders JOIN OrderParties ON Orders.Id = OrderParties.Order AND OrderParties.Type = 'Recipient' WHERE Orders.Status = 'Canceled'
Jawaban:
Aljabar relasional memungkinkan pertukaran predikat dalam
WHERE
klausa danINNER JOIN
, sehingga bahkanINNER JOIN
pertanyaan denganWHERE
klausa dapat membuat predikat disusun ulang oleh pengoptimal sehingga mereka mungkin sudah dikecualikan selamaJOIN
proses.Saya sarankan Anda menulis pertanyaan dengan cara yang paling mudah dibaca.
Kadang-kadang ini termasuk membuat yang
INNER JOIN
relatif "tidak lengkap" dan menempatkan beberapa kriteria dalamWHERE
hanya untuk membuat daftar kriteria penyaringan lebih mudah dipelihara.Misalnya, alih-alih:
Menulis:
Tapi itu tergantung, tentu saja.
sumber
Untuk inner joins, saya belum benar-benar memperhatikan perbedaan (tetapi seperti semua penyetelan kinerja, Anda perlu memeriksa database Anda di bawah kondisi Anda).
Namun di mana Anda meletakkan kondisi itu membuat perbedaan besar jika Anda menggunakan gabungan kiri atau kanan. Sebagai contoh, pertimbangkan dua pertanyaan ini:
Yang pertama hanya akan memberi Anda catatan-catatan yang memiliki pesanan tertanggal lebih dari 15 Mei 2009 sehingga mengubah bergabung kiri untuk bergabung dalam.
Yang kedua akan memberikan catatan-catatan itu ditambah pelanggan mana pun tanpa pesanan. Hasil yang ditetapkan sangat berbeda tergantung di mana Anda meletakkan kondisinya. (Pilih * hanya untuk tujuan saja, tentu saja Anda tidak boleh menggunakan ini dalam kode produksi.)
Pengecualian untuk ini adalah ketika Anda hanya ingin melihat catatan dalam satu tabel tetapi tidak yang lain. Kemudian Anda menggunakan klausa where untuk kondisi bukan join.
sumber
A left join B
adalah setiap baris dari A bergabung ke setiap baris yang cocok dari B. Jika B tidak memiliki baris yang cocok, maka kolom A memiliki nilai tetapi setiap kolom dari B pada baris itu ditampilkan sebagai nilai NULL. Jika Anda telah menuliswhere B.somecolumn = ‘somevalue’
maka Anda memiliki NULL (B.somecolumn) dibandingkan dengan 'somevalue'. Apa pun yang dibandingkan dengan NULL adalah salah, jadi semua baris Anda di mana tidak ada baris B yang cocok untuk baris A, dihilangkan, dan hasil yang Anda dapatkan adalah sama dengan yang akan diberikan INNER JOIN, maka sambungan luar telah menjadi bagian dalamfunds
bergabung dalam (prosp.id = funds.lead_id dan prosp.is_manual = 'tidak') dan SELECT funds.id, prospek.id DARIfunds
kiri bergabung dengan prospek pada (prosp.id = funds.lead_id) di mana prosp.is_manual = 'tidak'Sebagian besar produk RDBMS akan mengoptimalkan kedua pertanyaan secara identik. Dalam "SQL Performance Tuning" oleh Peter Gulutzan dan Trudy Pelzer, mereka menguji beberapa merek RDBMS dan tidak menemukan perbedaan kinerja.
Saya lebih suka untuk menjaga kondisi gabungan terpisah dari kondisi batasan kueri.
Jika Anda menggunakan
OUTER JOIN
kadang - kadang perlu untuk memasukkan kondisi dalam klausa gabungan.sumber
DIMANA akan menyaring setelah GABUNG telah terjadi.
Filter pada JOIN untuk mencegah baris ditambahkan selama proses JOIN.
sumber
ON
Saya lebih suka GABUNG untuk bergabung dengan tabel penuh / Tampilan dan kemudian gunakan WHERE Untuk memperkenalkan predikat set yang dihasilkan.
Secara sintaksis terasa lebih bersih.
sumber
Saya biasanya melihat peningkatan kinerja saat memfilter pada gabungan. Terutama jika Anda dapat bergabung di kolom yang diindeks untuk kedua tabel. Anda harus bisa mengurangi pembacaan logis dengan sebagian besar pertanyaan melakukan ini juga, yang, dalam lingkungan volume tinggi, indikator kinerja yang jauh lebih baik daripada waktu eksekusi.
Saya selalu sedikit geli ketika seseorang menunjukkan benchmark SQL mereka dan mereka telah mengeksekusi kedua versi sproc 50.000 kali pada tengah malam di server dev dan membandingkan waktu rata-rata.
sumber
Menempatkan kondisi dalam gabung tampaknya "semantik salah" bagi saya, karena bukan itu GABUNGAN "untuk". Tapi itu sangat kualitatif.
Masalah tambahan: jika Anda memutuskan untuk beralih dari gabung dalam ke, katakanlah, gabung kanan, memiliki kondisi di dalam GABUNGAN dapat menyebabkan hasil yang tidak terduga.
sumber
Bergabung lebih cepat menurut saya ketika Anda memiliki meja yang lebih besar. Sebenarnya tidak banyak perbedaan meskipun terutama jika Anda berurusan dengan meja yang lebih kecil. Ketika saya pertama kali belajar tentang bergabung, saya diberitahu bahwa kondisi dalam bergabung adalah seperti di mana kondisi klausa dan bahwa saya bisa menggunakannya secara bergantian jika klausa mana yang spesifik tentang tabel mana untuk melakukan kondisi.
sumber
Lebih baik menambahkan kondisi di Gabung. Kinerja lebih penting daripada keterbacaan. Untuk dataset besar, itu penting.
sumber