Membangun contoh FIND_IN_SET() dari @Jeremy Smith, Anda dapat melakukannya dengan join sehingga Anda tidak perlu menjalankan subquery.
SELECT * FROM table t
JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
WHERE l.e_ID = ?
Ini diketahui berkinerja sangat buruk, karena harus melakukan pemindaian tabel, mengevaluasi fungsi FIND_IN_SET() untuk setiap kombinasi baris dalam table
dan locations
. Itu tidak dapat menggunakan indeks, dan tidak ada cara untuk memperbaikinya.
Saya tahu Anda mengatakan bahwa Anda mencoba membuat yang terbaik dari desain basis data yang buruk, tetapi Anda harus memahami betapa buruknya hal ini secara drastis.
Penjelasan:Misalkan saya meminta Anda untuk mencari semua orang di buku telepon yang inisial pertama, tengah, atau terakhirnya adalah "J." Tidak mungkin urutan buku yang diurutkan membantu dalam kasus ini, karena Anda tetap harus memindai setiap halaman.
LIKE
solusi yang diberikan oleh @fthiella memiliki masalah yang sama berkaitan dengan kinerja. Itu tidak dapat diindeks.
Lihat juga jawaban saya untuk Apakah menyimpan daftar yang dibatasi dalam kolom database benar-benar buruk? untuk jebakan lain dari cara penyimpanan data yang didenormalisasi ini.
Jika Anda dapat membuat tabel tambahan untuk menyimpan indeks, Anda dapat memetakan lokasi ke setiap entri dalam daftar kota:
CREATE TABLE location2city (
location INT,
city INT,
PRIMARY KEY (location, city)
);
Dengan asumsi Anda memiliki tabel pencarian untuk semua kemungkinan kota (bukan hanya yang disebutkan dalam table
) Anda dapat menanggung inefisiensi satu kali untuk menghasilkan pemetaan:
INSERT INTO location2city (location, city)
SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
ON FIND_IN_SET(c.e_ID, l.city) > 0;
Sekarang Anda dapat menjalankan kueri yang jauh lebih efisien untuk menemukan entri di table
:
SELECT * FROM location2city l
JOIN table t ON t.e_ID = l.city
WHERE l.e_ID = ?;
Ini dapat menggunakan index. Sekarang Anda hanya perlu berhati-hati agar setiap INSERT/UPDATE/DELETE baris di locations
juga menyisipkan baris pemetaan yang sesuai di location2city
.