Ini tidak terlalu mudah untuk menjawab pertanyaan ini. Anda harus mengetahui satu hal penting:MySQL memperlakukan IN (<static values list>)
dan IN (<subquery>)
sebagai kueri yang berbeda
. Yang pertama sama dengan perbandingan rentang (seperti .. OR = .. OR =
) sedangkan detik sama dengan = ANY ()
- dan itu tidak sama. Jadi, singkatnya:menggunakan IN
dengan subquery akan menyebabkan kueri dengan ANY()
dan MySQL tidak akan menggunakan indeks untuk itu meskipun subquery independen dan mengembalikan daftar nilai statis . Sedih, tapi benar. MySQL tidak dapat memprediksi itu dan indeks tidak akan digunakan meskipun sudah jelas. Jika Anda akan menggunakan JOIN
(yaitu menulis ulang IN (<subquery>)
. Anda ) - maka MySQL akan menggunakan indeks untuk JOIN
kondisi, jika memungkinkan.
Sekarang, kasus kedua mungkin tentang JOIN
dan IN
saat menggunakan partisi. Jika Anda akan menggunakan JOIN
- kemudian, sayangnya - tetapi MySQL juga tidak dapat memprediksi partisi untuk JOIN
dalam kasus umum - dan itu akan menggunakan seluruh set partisi untuk itu. Mengganti JOIN
ke IN (<static list>)
akan mengubah EXPLAIN PARTITION
gambar:MySQL hanya akan menggunakan partisi tersebut, yang diperlukan untuk memilih nilai dari rentang, yang ditentukan dalam IN
ayat. Tapi, sekali lagi, ini tidak akan bekerja dengan IN (<subquery>)
.
Sebagai kesimpulan - menyedihkan, ketika kita mengatakan tentang bagaimana MySQL menangani IN
subqueries - dan biasanya tidak dapat diganti dengan JOIN
aman (itu tentang kasus partisi). Jadi, solusi umum adalah:pisahkan subkueri dari kueri utama pada level aplikasi . Jika kita mengatakan tentang subquery independen, mengembalikan daftar nilai statis, itu saran terbaik - maka Anda dapat mengganti daftar nilai itu sebagai IN(<static list>)
dan dapatkan manfaat:MySQL akan menggunakan indeks untuk itu, dan, jika kita mengatakan tentang partisi, hanya yang benar-benar dibutuhkan dari mereka yang akan digunakan.