Thông thường, khi nghĩ đến phân trang người ta sẽ nghĩ ngay đến việc dùng offset:
SELECT u.id, u.date, u.note, u.user_id
FROM user_notes AS u
ORDER BY u.date DESC, u.id DESC
LIMIT 1000 OFFSET 900000;
Tuy nhiên, cách làm này có một nhược điểm là DBMS phải duyệt qua n
record để đến được offset.
Thay vào đó, ta có thể sử dụng cursor pagination - tận dụng con trỏ để nhảy đến vị trí cần truy xuất data nhanh hơn. Về bản chất, thay vì dùng offset, ta sử dụng điều kiện WHERE
ở trên một (hoặc nhiều) cột có giá trị duy nhất mà được đánh index.
CREATE INDEX idx_user_notes_date_id ON user_notes (date DESC, id DESC); -- composite index on date and id
SELECT u.id, u.date, u.note, u.user_id
FROM user_notes AS u
WHERE (u.date, u.id) <= (@date, @lastId)
ORDER BY u.date DESC, u.id DESC
LIMIT 1000;
Trong câu truy vấn trên, @date
và @lastId
là giá trị của record cuối cùng trên trang trước đó.