Saya penasaran manakah dari berikut ini yang akan lebih efisien?
Saya selalu berhati-hati dalam menggunakan IN
karena saya percaya SQL Server mengubah hasil yang ditetapkan menjadi IF
pernyataan besar . Untuk kumpulan hasil yang besar, ini dapat mengakibatkan kinerja yang buruk. Untuk kumpulan hasil kecil, saya tidak yakin mana yang lebih disukai. Untuk kumpulan hasil yang besar, bukankah EXISTS
lebih efisien?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
vs.
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
sql-server
sql-server-2005
exists
query-performance
sql-in
Randy Minder
sumber
sumber
select 1 from Base...
di Andawhere exists
karena Anda tidak benar-benar peduli tentang hasil, hanya saja berturut-turut benar-benar ada.Jawaban:
EXISTS
akan lebih cepat karena setelah mesin menemukan tabrakan, mesin akan berhenti melihat sebagaimana kondisi terbukti benar.Dengan
IN
, itu akan mengumpulkan semua hasil dari sub-query sebelum diproses lebih lanjut.sumber
Jawaban yang diterima berpandangan pendek dan pertanyaannya agak longgar karena:
Saya yakin pengoptimal cukup pintar untuk mengonversi antara "dalam" vs "ada" ketika ada perbedaan biaya yang signifikan karena (1) dan (2), jika tidak, pengoptimal hanya dapat digunakan sebagai petunjuk (misalnya, ada untuk mendorong penggunaan indeks yang bisa dicari di sisi kanan).
Kedua formulir dapat dikonversi menjadi formulir gabungan secara internal, memiliki urutan gabungan dibalik, dan dijalankan sebagai loop, hash, atau penggabungan - berdasarkan perkiraan jumlah baris (kiri dan kanan) dan keberadaan indeks di kiri, kanan, atau kedua sisi.
sumber
IN
danEXISTS
. Coba dan temukan kasus di mana mereka tidak mendapatkan rencana yang sama (meskipun ini tidak berlaku untukNOT IN
danNOT EXISTS
)Saya telah melakukan beberapa pengujian pada SQL Server 2005 dan 2008, dan pada EXISTS dan IN kembali dengan rencana eksekusi aktual yang sama persis, seperti yang dinyatakan orang lain. Pengoptimal sudah optimal. :)
Sesuatu yang harus diperhatikan, EXISTS, IN, dan JOIN terkadang dapat memberikan hasil yang berbeda jika Anda tidak menyusun kueri dengan benar: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx
sumber
Ada banyak jawaban jawaban yang menyesatkan di sini, termasuk jawaban yang sangat disukai (meskipun saya tidak percaya operasi mereka berarti membahayakan). Jawaban singkatnya adalah: Ini sama.
Ada banyak kata kunci dalam bahasa SQL (T-), tetapi pada akhirnya, satu-satunya hal yang benar-benar terjadi pada perangkat keras adalah operasi seperti yang terlihat dalam rencana kueri eksekusi.
Operasi relasional (teori matematika) yang kita lakukan saat kita memanggil
[NOT] IN
dan[NOT] EXISTS
merupakan semi join (anti-join saat menggunakanNOT
). Bukan kebetulan bahwa operasi sql-server yang sesuai memiliki nama yang sama . Tidak ada operasi yang menyebutkanIN
atau diEXISTS
mana pun - hanya (anti-) semi bergabung. Dengan demikian, tidak ada cara bahwa pilihanIN
vs yang secara logis setaraEXISTS
dapat mempengaruhi kinerja karena hanya ada satu cara, operasi (anti) semi join execution, untuk mendapatkan hasilnya. .Sebuah contoh:
Kueri 1 ( rencana )
Kueri 2 ( rencana )
sumber
Saya akan memilih EXISTS daripada IN, lihat tautan di bawah ini:
SQL Server: JOIN vs IN vs EXISTS - perbedaan logis
Kredit blog: https://stackoverflow.com/users/31345/mladen-prajdic
sumber
Rencana eksekusi biasanya akan identik dalam kasus ini, tetapi sampai Anda melihat bagaimana faktor pengoptimal dalam semua aspek indeks lainnya, dll., Anda benar-benar tidak akan pernah tahu.
sumber
Jadi, IN tidak sama dengan EXISTS dan juga tidak akan menghasilkan rencana eksekusi yang sama.
Biasanya EXISTS digunakan dalam subkueri berkorelasi, itu berarti Anda akan BERGABUNG dengan kueri dalam yang ada dengan kueri luar Anda. Itu akan menambahkan lebih banyak langkah untuk menghasilkan hasil saat Anda perlu menyelesaikan kueri luar bergabung dan kueri dalam bergabung lalu mencocokkan klausa tempat mereka untuk menggabungkan keduanya.
Biasanya IN digunakan tanpa menghubungkan kueri dalam dengan kueri luar, dan itu bisa diselesaikan hanya dalam satu langkah (dalam skenario kasus terbaik).
Pertimbangkan ini:
Jika Anda menggunakan IN dan hasil query dalam adalah jutaan baris nilai yang berbeda, itu mungkin akan melakukan lebih lambat dari EXISTS mengingat bahwa query EXISTS adalah performant (memiliki indeks yang tepat untuk digabungkan dengan query luar).
Jika Anda menggunakan EXISTS dan penggabungan dengan kueri luar Anda rumit (membutuhkan lebih banyak waktu untuk melakukan, tidak ada indeks yang sesuai) itu akan memperlambat kueri dengan jumlah baris di tabel luar, terkadang perkiraan waktu untuk menyelesaikan bisa dalam beberapa hari. Jika jumlah baris dapat diterima untuk perangkat keras yang Anda berikan, atau kardinalitas datanya benar (misalnya nilai DISTINCT yang lebih sedikit dalam kumpulan data yang besar) IN dapat bekerja lebih cepat daripada EXISTS.
Semua hal di atas akan dicatat ketika Anda memiliki cukup banyak baris pada setiap tabel (maksud saya adalah sesuatu yang melebihi pemrosesan CPU Anda dan / atau ambang ram untuk caching).
Jadi JAWABANNYA TERGANTUNG. Anda dapat menulis kueri kompleks di dalam IN atau EXISTS, tetapi sebagai aturan praktis, Anda harus mencoba menggunakan IN dengan sekumpulan nilai berbeda dan EXISTS terbatas saat Anda memiliki banyak baris dengan banyak nilai berbeda.
Triknya adalah dengan membatasi jumlah baris yang akan dipindai.
Salam,
MarianoC
sumber
Untuk mengoptimalkan
EXISTS
, jadilah sangat literal; sesuatu harus ada di sana, tetapi Anda tidak benar-benar membutuhkan data apa pun yang dikembalikan dari sub-kueri terkait. Anda baru saja mengevaluasi kondisi Boolean.Begitu:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Karena sub-kueri terkait adalah
RBAR
, klik hasil pertama membuat kondisi menjadi benar, dan tidak diproses lebih lanjut.sumber
Tidak masuk akal dan tidak dijamin benar: Saya yakin yang kedua akan lebih cepat dalam kasus ini.
IN
wasiat akan mengalami korsleting segera setelah menemukan kecocokan.sumber