Menu

LIMIT dan OFFSET SQLite: Pagination dan Batasi Baris

Cara kerja LIMIT dan OFFSET di SQLite: membatasi baris, melewati baris, pagination yang aman, dan jebakan performa yang perlu dihindari di tabel besar.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

LIMIT Membatasi Jumlah Baris

LIMIT adalah pengatur paling sederhana di SQL: klausa ini memberi tahu SQLite "berikan paling banyak sekian baris." Taruh di akhir SELECT, dan kamu akan mendapat hasil sebanyak itu, tidak lebih, dan mungkin kurang jika tabelnya tidak punya cukup baris.

Kamu mendapat tiga baris pertama. Tapi tiga baris yang mana, tepatnya? Di situlah masalahnya: tanpa ORDER BY, SQLite memilih urutan apa pun yang menurutnya praktis. Hari ini mungkin urutan saat baris dimasukkan; besok, setelah ada update atau perubahan index, mungkin tidak lagi. LIMIT saja sudah cukup untuk "tunjukkan contoh datanya", tapi begitu urutannya penting, kamu perlu menuliskannya secara eksplisit.

OFFSET Melewati Baris dari Depan

Pasangkan LIMIT dengan OFFSET, dan kamu bisa meminta potongan dari tengah hasil query. OFFSET k membuang k baris pertama; lalu LIMIT n mengembalikan paling banyak n baris dari sisanya.

Artinya "lewati dua baris, kembalikan dua berikutnya", yaitu baris ke-3 dan ke-4 dari hasil yang sudah diurutkan. Model berpikirnya: WHERE memfilter, ORDER BY mengurutkan, OFFSET melewati, LIMIT membatasi. Semuanya berjalan dengan urutan itu, dan semuanya penting.

Pagination Selalu Butuh ORDER BY

Pemakaian LIMIT dan OFFSET yang paling umum adalah pagination: membagi daftar panjang menjadi halaman-halaman, misalnya 20 baris per halaman. Halaman 1 adalah LIMIT 20 OFFSET 0, halaman 2 adalah LIMIT 20 OFFSET 20, dan seterusnya.

Ada dua hal yang perlu diperhatikan. Pertama, ORDER BY tidak bisa ditawar: tanpanya, "halaman 2" tidak punya arti yang pasti dan baris-baris bisa teracak setiap kali halaman dimuat. Kedua, kunci pengurutannya menyertakan id sebagai penentu saat nilainya sama. Jika dua postingan punya created_at yang sama, kamu butuh kolom unik untuk memberi keduanya urutan yang pasti. Kalau tidak, posisinya bisa bertukar dan sebuah baris bisa bocor ke halaman lain.

Patokannya: urutkan berdasarkan sesuatu yang unik, atau urutkan berdasarkan kolom pengurutanmu ditambah satu kolom unik sebagai penentu.

Bentuk Singkat: LIMIT n, m

SQLite mendukung sintaks koma yang lebih lama demi kompatibilitas dengan MySQL: LIMIT offset, count. Artinya sama dengan LIMIT count OFFSET offset, tapi urutannya terbalik dan mudah salah dibaca.

-- These two are equivalent:
SELECT * FROM books LIMIT 10 OFFSET 20;
SELECT * FROM books LIMIT 20, 10;     -- offset first, then count

Bentuk kedua memang ringkas, tapi sering menjebak orang yang mengira angka pertamanya adalah jumlah baris. Tetap pakai LIMIT n OFFSET k: lebih eksplisit dan terbaca urut dari awal sampai akhir.

OFFSET Tanpa LIMIT: Trik LIMIT -1

OFFSET tidak sah jika berdiri sendiri, karena tata bahasa SQLite mengharuskannya muncul setelah LIMIT. Lalu bagaimana cara mengatakan "lewati 10 baris pertama dan berikan semua sisanya"? Konvensinya adalah LIMIT -1, yang dibaca SQLite sebagai "tanpa batas atas."

LIMIT negatif apa pun melakukan hal yang sama, tapi -1 adalah idiom yang sudah lazim. Kamu biasanya akan melihat ini di script yang menelusuri hasil per halaman dan butuh query "berikan sisanya" untuk kelompok terakhir.

Jebakan Performa OFFSET

Ini hal yang jarang dibahas sampai kamu sendiri mengalaminya: OFFSET tidak membuat SQLite melewatkan pekerjaan, tapi hanya melewatkan output. Untuk mengembalikan baris ke-10.001 sampai ke-10.020, engine-nya tetap menelusuri sepuluh ribu baris pertama secara internal sebelum mulai mengeluarkan hasil. Offset kecil tidak terasa; offset puluhan atau ratusan ribu jadi terasa lambat.

Untuk pagination yang dalam, solusi standarnya adalah keyset pagination: alih-alih "lewati N baris", ingat kunci pengurutan dari baris terakhir lalu minta "baris setelah yang ini."

Setiap halaman melakukan pencarian lewat index, bukan memindai melewati semua baris sebelumnya. Konsekuensinya: kamu tidak bisa melompat ke "halaman 47", hanya maju menelusuri data. Untuk feed infinite scroll dan cursor API, itulah yang kamu butuhkan.

Pagination berbasis OFFSET tidak masalah untuk tabel admin dan hasil query yang kecil. Untuk apa pun yang terus bertambah tanpa batas, pakai keyset pagination.

Contoh Lengkap

Semuanya digabungkan: query pagination dengan filter, pengurutan, dan penentu urutan yang pasti:

Saring hanya produk kantor, urutkan berdasarkan harga dari yang termurah dengan nama sebagai penentu saat harganya sama, lalu ambil dua yang pertama. Ganti OFFSET 0 menjadi OFFSET 2 untuk halaman 2. Query-nya pendek, tapi setiap klausanya punya peran.

Selanjutnya: DISTINCT

LIMIT mengatur berapa banyak baris yang dikembalikan; DISTINCT mengatur apakah duplikat dikembalikan atau tidak. Itulah klausa berikutnya di perangkat SELECT, dan klausa ini ternyata mudah disalahgunakan. Topik itu ada di halaman berikutnya.

Pertanyaan yang sering diajukan

Apa fungsi LIMIT di SQLite?

LIMIT n membatasi jumlah baris yang dikembalikan SELECT menjadi paling banyak n. Klausa ini berjalan setelah WHERE, GROUP BY, dan ORDER BY, jadi yang kamu batasi adalah hasil akhirnya, bukan baris yang dipindai query. SELECT * FROM users LIMIT 10 mengembalikan paling banyak sepuluh baris.

Bagaimana OFFSET bekerja bersama LIMIT di SQLite?

OFFSET k melewati k baris pertama dari hasil sebelum LIMIT mulai menghitung. Jadi LIMIT 10 OFFSET 20 mengembalikan baris ke-21 sampai ke-30. SQLite tetap harus menelusuri baris-baris yang dilewati itu secara internal, dan itulah sebabnya offset yang besar jadi lambat.

Bisakah memakai OFFSET tanpa LIMIT di SQLite?

Tidak secara langsung, karena OFFSET hanya sah sebagai bagian dari klausa LIMIT. Solusinya adalah LIMIT -1 OFFSET k, dengan -1 berarti 'tanpa batas atas', sehingga SQLite melewati k baris dan mengembalikan semua sisanya. Keunikan ini layak diingat.

Kenapa query pagination butuh ORDER BY?

Tanpa ORDER BY, SQLite bebas mengembalikan baris dalam urutan apa pun, dan urutan itu bisa berubah antarquery. Pagination pun jadi kacau: baris yang sama bisa muncul di halaman 1 dan halaman 3, atau hilang sama sekali. Selalu pasangkan LIMIT/OFFSET dengan ORDER BY pada kolom yang stabil dan unik.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai