ventajas español desventajas postgresql pagination paginate

postgresql - español - mongodb



Uso de "Cursores" para la paginación en PostgreSQL (2)

Posible duplicado:
¿Cómo proporcionar un cliente API con 1,000,000 resultados de base de datos?

Preguntarse por el uso de los Cursors es una buena forma de implementar la "paginación" utilizando PostgreSQL.

El caso de uso es que tenemos más de 100,000 filas que nos gustaría poner a disposición de nuestros clientes API. Pensamos que una buena manera de hacer que esto sucediera sería permitir al cliente solicitar la información en lotes (páginas). El cliente podría solicitar 100 filas a la vez. Devolveríamos las 100 filas así como un cursor, luego, cuando el cliente estuviera listo, podrían solicitar las siguientes 100 filas utilizando el cursor que les enviamos.

Sin embargo, estoy un poco confuso sobre cómo funcionan los cursores y exactamente cómo y cuándo deben usarse los cursores:

  • ¿Los cursores requieren que una conexión de base de datos se deje abierta?
  • ¿Se ejecutan los cursores dentro de una transacción, bloqueando los recursos hasta que se "cierran"?
  • ¿Hay otros "errores" de los que no estoy al tanto?
  • ¿Hay otra manera mejor de manejar esta situación?

¡Muchas gracias!


Los cursores son una opción razonable para la paginación en aplicaciones de intranet más pequeñas que funcionan con grandes conjuntos de datos, pero debe estar preparado para descartarlos después de un tiempo de espera. A los usuarios les gusta pasearse, ir a almorzar, irse de vacaciones por dos semanas, etc., y dejar sus aplicaciones en ejecución. Si se trata de una aplicación basada en la web, incluso existe la pregunta de qué es "correr" y cómo saber si el usuario todavía está presente.

No son adecuados para aplicaciones a gran escala con altos recuentos de clientes y clientes que van y vienen casi al azar, como en aplicaciones basadas en web o API web. No recomendaría usar cursores en su aplicación a menos que tenga un número de clientes bastante pequeño y tasas de solicitud muy altas ... en cuyo caso, el envío de pequeños lotes de filas será muy ineficaz y debería pensar en permitir solicitudes de rango, etc.

Los cursores tienen varios costes. Si el cursor no está WITH HOLD , debe mantener una transacción abierta. La transacción abierta puede evitar que Autovacuum haga su trabajo correctamente, causando la hinchazón de la mesa y otros problemas. Si el cursor se declara WITH HOLD y la transacción no se mantiene abierta, tendrá que pagar el costo de materializar y almacenar un conjunto de resultados potencialmente grande; al menos, creo que así es como funcionan los cursores de retención. La alternativa es igual de mala, mantener la transacción implícitamente abierta hasta que el cursor se destruya y evitar que se eliminen las filas.

Además, si está utilizando cursores, no puede devolver las conexiones a un grupo de conexiones. Necesitarás una conexión por cliente. Eso significa que se utilizan más recursos de back-end solo para mantener el estado de la sesión, y establece un límite superior muy real en la cantidad de clientes que puede manejar con un enfoque basado en el cursor.

También existe la complejidad y la sobrecarga de administrar una configuración basada en cursores y con estado en comparación con un enfoque de agrupación de conexiones sin estado con límite y desplazamiento. Es necesario que su aplicación expire los cursores después de un tiempo de espera o se enfrenta a un uso de recursos potencialmente ilimitado en el servidor, y debe hacer un seguimiento de qué conexiones tienen qué cursores para qué conjuntos de resultados para qué usuarios ...

En general, a pesar de que puede ser bastante ineficiente, LIMIT y OFFSET pueden ser la mejor solución. Sin embargo, a menudo puede ser mejor buscar la clave principal en lugar de usar OFFSET .

Por cierto, estabas mirando la documentación de los cursores en PL / pgSQL. Desea cursores normales de nivel SQL para este trabajo.

¿Los cursores requieren que una conexión de base de datos se deje abierta?

Sí.

¿Se ejecutan los cursores dentro de una transacción, bloqueando los recursos hasta que se "cierran"?

Sí, a menos que estén en WITH HOLD , en cuyo caso consumen otros recursos de base de datos.

¿Hay otros "errores" de los que no estoy al tanto?

Sí, como lo explicado anteriormente.


Para los clientes HTTP, no use cursores para implementar la paginación. Para la escalabilidad, no desea que los recursos del servidor se vinculen entre las solicitudes.

En su lugar, use LIMIT y OFFSET en sus consultas; Ver LIMIT y OFFSET en los documentos Pg .

Pero asegúrese de que la indexación en sus tablas admita consultas eficientes de este formulario.

Diseñe una API REST, para que el cliente pueda invocar el "next_url" (también pasado en la respuesta) para obtener el siguiente conjunto de filas.