Tampak bagi saya bahwa Anda dapat melakukan hal yang sama dalam query SQL menggunakan BUKAN ADA, BUKAN DALAM, atau KIRI BERGABUNG DI MANA NULL. Sebagai contoh:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)
SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)
SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
Saya tidak yakin apakah saya sudah mendapatkan semua sintaks yang benar, tetapi ini adalah teknik umum yang saya lihat. Mengapa saya memilih untuk menggunakan salah satu dari yang lain? Apakah kinerjanya berbeda ...? Yang mana yang paling cepat / paling efisien? (Jika itu tergantung pada implementasi, kapan saya akan menggunakan masing-masing?)
EXISTS
klausa. Anda dapat kembali*
,NULL
atau apa pun: semua ini akan dioptimalkan jauh.SELECT
danFROM
. Dan*
hanya lebih mudah untuk mengetik. Ya,SQL
memang memiliki kemiripan dengan bahasa alami, tetapi diurai dan dieksekusi oleh mesin, mesin yang diprogram. Bukannya itu akan tiba-tiba menerobos masuk ke dalam bilik Anda dan berteriak "berhenti menuntut bidang tambahan dalamEXISTS
kueri karena saya muak mengurai mereka dan kemudian membuangnya!". Tidak apa-apa dengan komputer, sungguh.Jawaban:
TIDAK DI vs. TIDAK ADA vs. LEFT BERGABUNG / IS NULL: SQL Server
TIDAK DI vs. TIDAK ADA vs. LEFT BERGABUNG / ADALAH NULL: PostgreSQL
TIDAK DI vs. TIDAK ADA vs. LEFT BERGABUNG / IS NULL: Oracle
BUKAN DALAM BUKAN vs. TIDAK ADA vs. LEFT BERGABUNG / ADALAH NULL: MySQL
Pendeknya:
NOT IN
sedikit berbeda: tidak pernah cocok jika hanya ada satuNULL
dalam daftar.Dalam
MySQL
,NOT EXISTS
sedikit kurang efisienDi
SQL Server
,LEFT JOIN / IS NULL
kurang efisienDi
PostgreSQL
,NOT IN
kurang efisienDalam
Oracle
, ketiga metode itu sama.sumber
table1 .a
mengandungNULL
satuEXISTS
permintaan tidak akan kembali baris ini tetapiNOT IN
akan query jikatable2
kosong. BUKAN vs. TIDAK ADA Kolom yang Tidak Dapat Diabaikan: SQL ServerNULL NOT IN ()
dievaluasi ke true (tidakNULL
), sama sepertiNOT EXISTS (NULL = column)
NOT EXISTS
akan selalu kembali baris tapiNOT IN
hanya akan melakukannya jika sub query tidak mengembalikan baris.Jika database bagus dalam mengoptimalkan kueri, dua yang pertama akan ditransformasikan menjadi sesuatu yang dekat dengan yang ketiga.
Untuk situasi sederhana seperti yang ada di pertanyaan Anda, seharusnya ada sedikit atau tidak ada perbedaan, karena semuanya akan dieksekusi sebagai gabungan. Dalam kueri yang lebih kompleks, basis data mungkin tidak dapat membuat gabungan dari
not in
dannot exists
kueri. Dalam hal ini permintaan akan jauh lebih lambat. Di sisi lain, gabungan juga dapat berkinerja buruk jika tidak ada indeks yang dapat digunakan, jadi hanya karena Anda menggunakan gabungan tidak berarti Anda aman. Anda harus memeriksa rencana pelaksanaan kueri untuk mengetahui apakah mungkin ada masalah kinerja.sumber
Dengan asumsi Anda menghindari nol, mereka semua cara menulis anti-bergabung menggunakan SQL Standar.
Kelalaian jelas setara dengan menggunakan
EXCEPT
:Catatan di Oracle Anda harus menggunakan
MINUS
operator (bisa dibilang nama yang lebih baik):Berbicara tentang sintaksis berpemilik, mungkin ada ekuivalen non-standar yang layak diselidiki tergantung pada produk yang Anda gunakan misalnya
OUTER APPLY
dalam SQL Server (sesuatu seperti):sumber
Ketika perlu memasukkan data dalam tabel dengan kunci primer multi-bidang, pertimbangkan bahwa itu akan jauh lebih cepat (saya mencoba di Access tapi saya pikir di Database apa pun) untuk tidak memeriksa bahwa "tidak ada catatan dengan nilai 'seperti' dalam tabel", - bukan hanya memasukkan ke dalam tabel, dan catatan berlebih (dengan kunci) tidak akan dimasukkan dua kali.
sumber
Perspektif kinerja selalu menghindari penggunaan kata kunci terbalik seperti BUKAN DALAM, BUKAN ADA, ... Karena untuk memeriksa item terbalik, DBMS perlu menjalankan semua yang tersedia dan menjatuhkan pilihan terbalik.
sumber
NOT
?