Use LIMIT
, WHERE
, OFFSET
to generate a page listing.
SELECT * FROM users
WHERE team_id = %team_id
ORDER BY id DESC
LIMIT 20 OFFSET 40;
You can count the number of pages:
SELECT COUNT(*) AS total FROM users WHERE team_id = %team_id;
This is simple, but doesn't scale, as the database has to read data up to the offset + count of rows from disk, and then do a filter.
This is almost always a SEQ SCAN
, which is I/O
heavy.
If items are being rewritten to the dataset or updated frequently, the window becomes unreliable, skipping, or returning duplicate results.
Pick a unique, sequential column to paginate on.
The client requests for a table and the count of items they want from it.
The server queries for the count + 1 item:
SELECT * FROM users
WHERE team_id = $(team_id)
ORDER BY id DESC
LIMIT $(count + 1)
and returns a response like so:
{
"data": ["..."],
"next_cursor": "123456" // user id of extra result.
}
The client then provides the next_cursor
as
cursor
in the second request.
SELECT * FROM users
WHERE team_id = $(team_id)
AND id <= $(cursor)
ORDER BY id DESC
LIMIT $(count + 1)
where
on a column that is easily indexable,
which means the query planner doesn't have to look at rows it doesn't
need to.Prev: security-and-https