Gunakan IN BOOLEAN MODE
.
Indeks tanggal tidak berguna. Tidak ada cara untuk menggabungkan kedua indeks.
Hati-hati, jika pengguna mencari sesuatu yang muncul dalam 30 ribu baris, kueri akan lambat. Tidak ada yang langsung di sekitarnya.
Saya menduga Anda memiliki TEXT
kolom dalam tabel? Jika demikian, ada harapan. Daripada membabi buta melakukan SELECT *
, pertama-tama mari kita temukan id dan dapatkan LIMIT
diterapkan, lalu lakukan *
.
SELECT a.*
FROM tbl AS a
JOIN ( SELECT date, id
FROM tbl
WHERE MATCH(...) AGAINST (...)
ORDER BY date DESC
LIMIT 10 ) AS x
USING(date, id)
ORDER BY date DESC;
Bersama dengan
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
Formulasi dan pengindeksan ini akan berfungsi seperti ini:
- Gunakan
FULLTEXT
untuk menemukan 30 ribu baris, kirim PK. - Dengan PK, urutkan 30 ribu baris menurut
date
. - Pilih 10 terakhir, kirim
date, id
- Mencapai kembali tabel 10 kali menggunakan PK.
- Urutkan lagi. (Ya, ini perlu.)
Lainnya (Menanggapi kebanyakan Komentar):
Tujuan di balik perumusan ulang saya adalah untuk menghindari pengambilan semua kolom 30rb baris. Sebagai gantinya, ia hanya mengambil PRIMARY KEY
, lalu kurangi menjadi 10, lalu ambil *
hanya 10 baris. Jauh lebih sedikit barang yang disekop.
Tentang COUNT
pada tabel InnoDB:
- INDEX(col) membuatnya menjadi indeks pemindaian berfungsi untuk
SELECT COUNT(*)
atauSELECT COUNT(col)
tanpaWHERE
. - Tanpa
INDEX(col),
SELECT COUNT(*)will use the "smallest" index; but
SELECT COUNT(col)` akan membutuhkan tabel pindai. - Pemindaian tabel biasanya lebih lambat dari pemindaian indeks.
- Hati-hati dengan pengaturan waktu -- Ini sangat dipengaruhi oleh apakah indeks dan/atau tabel sudah di-cache di RAM.
Hal lain tentang FULLTEXT
adalah +
di depan kata-kata -- untuk mengatakan bahwa setiap kata harus ada, kalau tidak, tidak ada yang cocok. Ini dapat mengurangi 30K.
FULLTEXT
index akan mengirimkan date, id
adalah pesanan acak, bukan pesanan PK. Bagaimanapun, adalah 'salah' untuk mengasumsikan pemesanan apa pun, oleh karena itu adalah 'benar' untuk menambahkan ORDER BY
, lalu biarkan Pengoptimal membuangnya jika tahu bahwa itu berlebihan. Dan terkadang Pengoptimal dapat memanfaatkan ORDER BY
(tidak dalam kasus Anda).
Menghapus hanya ORDER BY
, dalam banyak kasus, membuat kueri berjalan lebih cepat. Ini karena ia menghindari pengambilan, katakanlah, 30 ribu baris dan pengurutannya. Alih-alih, itu hanya memberikan 10 baris "apa saja".
(Saya belum berpengalaman dengan Postgres, jadi saya tidak bisa menjawab pertanyaan itu.)