Inilah yang saya lakukan, dan mengurangi total waktu eksekusi dengan faktor 10.
Apa yang saya sadari dari rencana eksekusi kueri asli saya adalah bahwa ia menggunakan filesort untuk menyortir semua hasil dan mengabaikan indeks. Itu sedikit sia-sia.
Basis data pengujian saya:5 M catatan, ukuran 20 GB. struktur tabel sama seperti pada pertanyaan
Alih-alih mendapatkan blobCol langsung di kueri pertama, saya pertama-tama mendapatkan nilai 'nama' untuk awal setiap halaman. Jalankan kueri ini tanpa batas hingga mengembalikan 0 hasil. Setiap kali, tambahkan hasilnya ke daftar
SELECT name
FROM my_table
where id = <anyId> // I use the id column for partitioning so I need this here
order by name
limit <pageSize * pageNumber>, 1
Nomor halaman sinus tidak diketahui sebelumnya, mulai dengan nilai 0 dan terus bertambah hingga kueri mengembalikan nol. Anda juga dapat melakukan penghitungan pilih (*) tetapi itu sendiri mungkin memakan waktu lama dan tidak akan membantu mengoptimalkan apa pun. Setiap kueri membutuhkan waktu sekitar 2 detik untuk dijalankan setelah nomor halaman melebihi ~60.
Bagi saya, ukuran halaman adalah 5000 jadi saya mendapat daftar string 'nama' di posisi 0, 5001, 10001, 15001, dan seterusnya. Jumlah halamannya ternyata 1000 dan menyimpan daftar 1000 hasilnya di memori tidaklah mahal.
Sekarang, ulangi daftar dan jalankan kueri ini
SELECT blobCol
FROM my_table
where name >= <pageHeader>
and name < <nextPageHeader>
and city="<any string>"
and id= 1
Ini akan berjalan N kali, di mana N =ukuran daftar yang diperoleh sebelumnya. Karena 'nama' adalah kolom kunci utama, dan 'kota' juga diindeks, EXPLAIN menunjukkan bahwa perhitungan ini dilakukan di memori menggunakan indeks.
Sekarang, setiap kueri membutuhkan waktu 1 detik untuk dijalankan, bukan 30-40 yang asli. Jadi menggabungkan waktu pra-pemrosesan 2 detik per halaman, total waktu per halaman adalah 3-4 detik, bukan 30-40.
Jika ada yang punya solusi yang lebih baik atau jika ada yang salah dengan yang ini, beri tahu saya