Kueri ini:
SELECT *
FROM listings
WHERE (publishedon BETWEEN 1441105258 AND 1443614458) AND
(published = 1) AND
(cat_id in (1,2,3,4,5)) AND
(source_id in (1,2,3,4,5));
Sulit untuk dioptimalkan hanya dengan indeks. Indeks terbaik adalah yang dimulai dengan published
dan kemudian memiliki kolom lainnya -- tidak jelas urutannya seperti apa. Alasannya adalah karena semua kecuali published
tidak menggunakan =
.
Karena masalah kinerja Anda sedang diurutkan, itu menunjukkan bahwa banyak baris yang dikembalikan. Biasanya, indeks digunakan untuk memenuhi WHERE
klausa sebelum indeks dapat digunakan untuk ORDER BY
. Itu membuat ini sulit untuk dioptimalkan.
Saran . . . Tidak ada yang sehebat itu:
- Jika Anda akan mengakses data berdasarkan bulan, maka Anda dapat mempertimbangkan untuk mempartisi data berdasarkan bulan. Itu akan membuat kueri tanpa
ORDER BY
lebih cepat, tetapi tidak akan membantuORDER BY
. - Coba berbagai urutan kolom setelah
published
dalam indeks. Anda mungkin menemukan kolom yang paling selektif. Namun, sekali lagi, ini mempercepat kueri sebelum pengurutan. - Pikirkan tentang cara Anda dapat menyusun kueri untuk memiliki lebih banyak kondisi kesetaraan di
WHERE
klausa atau untuk mengembalikan kumpulan data yang lebih kecil. - (Tidak disarankan) Letakkan indeks pada
published
dan kolom pemesanan. Kemudian gunakan subquery untuk mengambil data. Masukkan kondisi pertidaksamaan (IN
dan seterusnya) di kueri luar. Subquery akan menggunakan indeks untuk menyortir dan memfilter hasilnya.
Alasan terakhir tidak direkomendasikan adalah karena SQL (dan MySQL) tidak menjamin pengurutan hasil dari subquery. Namun, karena MySQL mewujudkan subquery, hasilnya benar-benar teratur. Saya tidak suka menggunakan efek samping yang tidak terdokumentasi, yang dapat berubah dari versi ke versi.