Memberi nomor halaman pada hasil penelusuran

Aplikasi web sering kali membuat penomoran halaman data saat ditampilkan kepada pengguna. Pengguna akhir menerima satu halaman hasil, dan saat mereka membuka halaman berikutnya, kumpulan hasil berikutnya akan diambil dan ditampilkan. Halaman ini menjelaskan cara menambahkan pempaginan ke hasil penelusuran saat melakukan penelusuran teks lengkap di Spanner.

Opsi penomoran halaman

Ada dua cara untuk menerapkan kueri yang di-pagination di Spanner: penomoran halaman berbasis kunci (direkomendasikan) dan penomoran halaman berbasis offset.

Penomoran halaman berbasis kunci adalah metode untuk mengambil hasil penelusuran dalam bagian yang lebih kecil dan lebih mudah dikelola sekaligus memastikan hasil yang konsisten di seluruh permintaan. ID unik ("kunci") dari hasil terakhir halaman digunakan sebagai titik referensi untuk mengambil kumpulan hasil berikutnya.

Spanner umumnya merekomendasikan penggunaan penomoran halaman berbasis kunci. Meskipun pagination berbasis offset lebih mudah diterapkan, pagination ini memiliki dua kelemahan yang signifikan:

  1. Biaya kueri yang lebih tinggi:Penomoran halaman berbasis offset berulang kali mengambil dan membuang hasil yang sama, sehingga meningkatkan biaya dan menurunkan performa.
  2. Hasil yang Tidak Konsisten: Dalam kueri dengan penomoran halaman, setiap halaman biasanya diambil pada stempel waktu baca yang berbeda. Misalnya, halaman pertama mungkin berasal dari kueri pada pukul 13.00, dan halaman berikutnya dari kueri pada pukul 23.10. Artinya, hasil penelusuran dapat berubah di antara kueri, sehingga menghasilkan hasil yang tidak konsisten di seluruh halaman.

Di sisi lain, penomoran halaman berbasis kunci menggunakan ID unik (kunci) dari hasil terakhir halaman untuk mengambil kumpulan hasil berikutnya. Hal ini memastikan pengambilan yang efisien dan hasil yang konsisten, meskipun data pokok berubah.

Untuk memberikan stabilitas dalam hasil halaman, aplikasi dapat mengeluarkan semua kueri untuk halaman yang berbeda pada stempel waktu yang sama. Namun, hal ini mungkin gagal jika kueri melebihi periode retensi versi (defaultnya adalah 1 jam). Misalnya, kegagalan ini terjadi jika version_gc adalah satu jam, dan pengguna akhir mengambil hasil pertama pada pukul 13.00 dan mengklik Berikutnya pada pukul 15.00.

Menggunakan penomoran halaman berbasis kunci

Penomoran halaman berbasis kunci mengingat item terakhir dari halaman sebelumnya dan menggunakannya sebagai titik awal untuk kueri halaman berikutnya. Untuk mencapai hal ini, kueri harus menampilkan kolom yang ditentukan dalam klausa ORDER BY dan membatasi jumlah baris menggunakan LIMIT.

Agar penomoran halaman berbasis kunci berfungsi, kueri harus mengurutkan hasil menurut beberapa urutan total yang ketat. Cara termudah untuk mendapatkannya adalah dengan memilih total urutan, lalu menambahkan kolom pemutus, jika diperlukan. Pada umumnya, urutan total adalah urutan pengurutan indeks penelusuran dan kombinasi kolom unik adalah kunci utama tabel dasar.

Dengan menggunakan skema contoh Albums, untuk halaman pertama, kueri akan terlihat seperti berikut:

SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 10;

AlbumId adalah pemecah seri karena ReleaseTimestamp bukan kunci. Mungkin ada dua album berbeda dengan nilai yang sama untuk ReleaseTimestamp.

Untuk melanjutkan, aplikasi menjalankan kueri yang sama lagi, tetapi dengan klausa WHERE yang membatasi hasil dari halaman sebelumnya. Kondisi tambahan harus memperhitungkan arah kunci (naik versus turun), pemecah seri, dan urutan nilai NULL untuk kolom nullable.

Dalam contoh kita, AlbumId adalah satu-satunya kolom kunci (dalam urutan menaik) dan tidak boleh NULL, sehingga kondisinya adalah sebagai berikut:

SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE (ReleaseTimestamp < @last_page_release_timestamp
       OR (ReleaseTimestamp = @last_page_release_timestamp
           AND AlbumId > @last_page_album_id))
      AND SEARCH(AlbumTitle_Tokens, @p)
ORDER BY ReleaseTimestamp DESC, AlbumId ASC
LIMIT @page_size;

Spanner menafsirkan jenis kondisi ini sebagai dapat dicari. Ini berarti bahwa Spanner tidak membaca indeks untuk dokumen yang Anda filter keluar. Pengoptimalan ini yang membuat penomoran halaman berbasis kunci jauh lebih efisien daripada penomoran halaman berbasis offset.

Menggunakan penomoran halaman berbasis offset

Penomoran halaman berbasis offset memanfaatkan klausa LIMIT dan OFFSET dari kueri SQL untuk menyimulasikan halaman. Nilai LIMIT menunjukkan jumlah hasil per halaman. Nilai OFFSET ditetapkan ke nol untuk halaman pertama, ukuran halaman untuk halaman kedua, dan dua kali ukuran halaman untuk halaman ketiga.

Misalnya, kueri berikut mengambil halaman ketiga, dengan ukuran halaman 50:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 50 OFFSET 100;

Catatan Penggunaan:

  • Klausa ORDER BY sangat direkomendasikan untuk memastikan pengurutan yang konsisten di antara halaman.
  • Dalam kueri produksi, gunakan parameter kueri, bukan konstanta, untuk menentukan LIMIT dan OFFSET agar penyimpanan dalam cache kueri lebih efisien. Untuk mengetahui informasi selengkapnya, lihat Parameter kueri.

Langkah selanjutnya