Hello my dear friends. In this article I will talk about PostgreSQL and pagination.
Pagination in simple way
Let’s start with simple examples. A query to fetch the 10 most recent news:
In SQL we are using ORDER BY to get most recent first news and LIMIT to fetch only the first 10 news.
Worst Case: No index for ORDER BY
The limiting factor is the number of rows that match the WHERE condition. The database might use an index to satisfy the WHERE condition, but must still fetch all matching rows to sort them.
Fetch Next Page
To get next resent 10 news in most cases using OFFSET:
Worst Case: No index for ORDER BY
As you can see by EXPLAIN for each next page need more memory to sort rows, before to do OFFSET and LIMIT. This might become the limiting factor when browsing farther back. Fetching the last page can take considerably longer than fetching the first page.
Improvement #1: Indexed ORDER BY
To impove pagination we should have indexes for fields, which we are using in ORDER BY:
The same index can be using in WHERE and ORDER BY.
As you can see, fetching the next page is also faster. But in order to select, for example, the 10 page (10 per page), PostgreSQL should select 100 records and make offset 90 of selected rows.
Improvement #2: The Seek Method
To remove the rows from previous pages we can use WHERE filter instead of OFFSET.
In this case neither the size of the base set(*) nor the fetched page number affects the response time. And the memory footprint is very low!
Examples:
But the Seek Method has serious limitations:
You cannot directly navigate to arbitrary pages (because you need the values from the previous page)
Bi-directional navigation is possible but tedious (you need to revers the ORDER BY direction and WHERE comparison)
Works best with full row values support (workaround is possible, but ugly and less performant)
Use case
The Seek Method perfect for “Infinite Scrolling” and “Next-Prev” (only this button) navigations:
This types of paginations doesn’t need:
navigate to arbitrary pages
browse backwards (only for “Prev-Next” navigation)
show total pages
Summary
As you can see, pagination can be improved by using an indexes (duh..) and the seek method. Last one can improve performance of pagination, but it can be used only for several types of paginations.