Aller au contenu
← Tous les articles

Backend1 min de lecture

PostgreSQL : paginer sans OFFSET

OFFSET relit toutes les lignes qu’il saute. La pagination par curseur garde un temps de réponse constant, même à la page mille.

Réseau clairsemé de nœuds bleus et de liaisons fines
Sommaire

LIMIT 20 OFFSET 20000 oblige la base à lire et jeter vingt mille lignes. Sur une table active, les pages lointaines deviennent lentes et les résultats peuvent sauter ou se répéter quand des lignes sont insérées.

Le curseur

On mémorise la dernière ligne vue et on repart de là :

SQL
SELECT id, title, published_at
FROM article
WHERE (published_at, id) < ($1, $2)
ORDER BY published_at DESC, id DESC
LIMIT 20;

Avec un index sur (published_at DESC, id DESC), chaque page coûte le même temps.

Les limites

  • Pas de saut direct vers une page lointaine
  • Le tri doit être total : on ajoute toujours la clé primaire
  • Le curseur doit être opaque pour le client

Pour une liste d’articles de quelques dizaines d’éléments, OFFSET reste le bon choix : les numéros de page sont plus utiles au lecteur que quelques millisecondes.

  • #PostgreSQL
  • #Performance
  • #API

Partager

Un projet, une question ?

Cet article vous a donné une idée, ou vous bloquez sur un problème proche ? Écrivez-moi, je réponds à chaque message.