Tabel memiliki kunci utama. Manfaatkan itu.
Alih-alih LIMIT
dan OFFSET
, lakukan paging Anda dengan filter pada kunci utama. Anda mengisyaratkan hal ini dengan komentar Anda:
Paging menggunakan nomor acak ( Tambahkan "LEBIH BESAR DARI ORDER BY " ke setiap kueri)
tapi tidak ada yang acak tentang bagaimana Anda harus melakukannya.
SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2
Izinkan klien untuk menentukan kedua parameter, ID terakhir yang dilihatnya, dan jumlah rekaman yang akan diambil. API Anda harus memiliki placeholder, parameter tambahan, atau panggilan alternatif untuk "ambil pertama n ID" di mana ia menghilangkan WHERE
klausa dari kueri, tapi itu sepele.
Pendekatan ini akan menggunakan pemindaian indeks yang cukup efisien untuk mendapatkan catatan secara berurutan, umumnya menghindari pengurutan atau kebutuhan untuk mengulangi semua catatan yang dilewati. Klien dapat memutuskan berapa banyak baris yang diinginkan sekaligus.
Pendekatan ini berbeda dari LIMIT
dan OFFSET
pendekatan dalam satu cara utama:modifikasi bersamaan. Jika Anda INSERT
ke dalam tabel dengan kunci bawah daripada kunci yang telah dilihat beberapa klien, pendekatan ini tidak akan mengubah hasilnya sama sekali, sedangkan OFFSET
pendekatan akan mengulangi satu baris. Demikian pula, jika Anda DELETE
baris dengan ID yang lebih rendah dari yang sudah dilihat, hasil dari pendekatan ini tidak akan berubah, sedangkan OFFSET
akan melewatkan baris yang tidak terlihat. Namun, tidak ada perbedaan untuk tabel append-only dengan kunci yang dibuat.
Jika Anda tahu sebelumnya bahwa klien akan menginginkan seluruh rangkaian hasil, hal yang paling efisien untuk dilakukan adalah mengirimkan mereka seluruh rangkaian hasil tanpa bisnis paging ini. Di situlah saya akan menggunakan kursor. Baca baris dari DB dan kirimkan ke klien secepat klien akan menerimanya. API ini perlu menetapkan batas seberapa lambat klien diizinkan untuk menghindari beban backend yang berlebihan; untuk klien yang lambat saya mungkin akan beralih ke paging (seperti yang dijelaskan di atas) atau menggulung seluruh hasil kursor ke file sementara dan menutup koneksi DB.
Peringatan penting :
- Memerlukan
UNIQUE
batasan /UNIQUE
indeks atauPRIMARY KEY
dapat diandalkan - Perilaku modifikasi bersamaan yang berbeda untuk membatasi/mengimbangi, lihat di atas