OFFSET/LIMIT (LIMIT 20 OFFSET 100000) buộc DB quét và bỏ đi toàn bộ hàng trước offset rồi mới trả 20 hàng → càng lật sâu càng chậm (chi phí tăng tuyến tính theo offset). Thêm rủi ro: nếu dữ liệu chèn/xóa giữa các lần lật, hàng có thể bị trùng hoặc bỏ sót.
Keyset pagination (seek method): thay vì đếm offset, dùng giá trị của hàng cuối trang trước làm mốc trong WHERE:
sql
SELECT * FROM posts
WHERE (created_at, id) < (:last_created_at, :last_id)
ORDER BY created_at DESC, id DESC
LIMIT 20;- DB nhảy thẳng tới vị trí nhờ index trên
(created_at, id)→ nhanh và ổn định dù offset lớn. - Ổn định trước thay đổi dữ liệu (không lệch trang).
- Đánh đổi: khó "nhảy tới trang N" tùy ý; hợp cuộn vô hạn / "tải thêm" hơn là dãy số trang.
Cần một khóa sắp xếp duy nhất và có thứ tự (thường thêm id để phá hòa).