La tabla tiene una clave principal. Haz uso de ella.
En lugar de LIMIT
y OFFSET
, haga su paginación con un filtro en la clave principal. Usted insinuó esto con su comentario:
Paginación usando números aleatorios (Agregue "MAYOR QUE ORDENADO POR" a cada consulta)
pero no hay nada aleatorio sobre cómo debes hacerlo.
SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2
Permita que el cliente especifique ambos parámetros, la última identificación que vio y la cantidad de registros para obtener. Su API deberá tener un marcador de posición, un parámetro adicional o una llamada alternativa para "buscar el primero n IDs" donde omite el WHERE
cláusula de la consulta, pero eso es trivial.
Este enfoque utilizará un escaneo de índice bastante eficiente para ordenar los registros, generalmente evitando una ordenación o la necesidad de iterar a través de todos los registros omitidos. El cliente puede decidir cuántas filas quiere a la vez.
Este enfoque difiere del LIMIT
y OFFSET
enfoque de una manera clave:modificación concurrente. Si INSERT
en la mesa con una tecla inferior que una clave que algún cliente ya ha visto, este enfoque no cambiará sus resultados en absoluto, mientras que el OFFSET
enfoque repetirá una fila. Del mismo modo, si DELETE
una fila con un ID inferior al ya visto, los resultados de este enfoque no cambiarán, mientras que OFFSET
saltará una fila invisible. Sin embargo, no hay diferencia para las tablas de solo agregar con claves generadas.
Si sabe de antemano que el cliente querrá el conjunto de resultados completo, lo más eficiente que puede hacer es enviarle el conjunto de resultados completo sin nada de este negocio de paginación. Ahí es donde yo lo haría utiliza un cursor. Lea las filas de la base de datos y envíelas al cliente tan rápido como el cliente las acepte. Esta API necesitaría establecer límites sobre la lentitud del cliente para evitar una carga de back-end excesiva; para un cliente lento, probablemente cambiaría a paginación (como se describe arriba) o colocaría todo el resultado del cursor en un archivo temporal y cerraría la conexión a la base de datos.
Advertencias importantes :
- Requiere un
UNIQUE
restricción /UNIQUE
índice oPRIMARY KEY
ser confiable - Diferente comportamiento de modificación concurrente para limitar/compensar, ver arriba