Antipatrón: OFFSET profundo — pasar a keyset
OFFSET 20000 lee y descarta 20 000 filas en cada página. La paginación keyset (seek) reanuda desde el último elemento visto: coste constante sea cual sea la profundidad.
Requisitos
Index sur les colonnes de tri (created_at DESC, id DESC)
SQL
-- Anti-pattern : la page 1000 lit 20 020 lignes pour en garder 20
SELECT * FROM products
ORDER BY created_at DESC, id DESC
LIMIT 20 OFFSET 20000;
-- Correctif : keyset — on repart du dernier élément de la page précédente
SELECT * FROM products
WHERE (created_at, id) < ('2026-06-01 12:34:56', 18432)
ORDER BY created_at DESC, id DESC
LIMIT 20;
-- Le tuple (created_at, id) garantit un ordre total même à timestamp égalResultado
id | created_at | name -------+---------------------+----------- 18431 | 2026-06-01 12:31:08 | Produit A 18419 | 2026-06-01 12:18:55 | Produit B 18402 | 2026-06-01 11:59:02 | Produit C (20 rows) -- OFFSET 20000 : Execution Time: 412.480 ms (lit 20 020 lignes) -- Keyset : Execution Time: 0.524 ms (lit 20 lignes)
SQLPaginationKeysetPerformance