sql >> Base de Datos >  >> RDS >> PostgreSQL

Uso de cursores para paginación en PostgreSQL

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 deambular, ir a almorzar, irse de vacaciones por dos semanas, etc., y dejar sus aplicaciones funcionando. Si se trata de una aplicación basada en la web, incluso existe la cuestión de qué es "ejecutar" y cómo saber si el usuario todavía está presente.

No son adecuados para aplicaciones a gran escala con una gran cantidad de clientes y clientes que van y vienen casi al azar, como en las aplicaciones basadas en web o las 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 enviar pequeños lotes de filas será muy ineficiente y debería pensar en permitir solicitudes de rango, etc. en su lugar.

Los cursores tienen varios costos. Si el cursor no está WITH HOLD debe mantener una transacción abierta. La transacción abierta puede evitar que el vacío automático haga su trabajo correctamente, lo que provoca que la tabla se hinche y otros problemas. Si el cursor se declara WITH HOLD y la transacción no se mantiene abierta, debe 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 se destruya el cursor y evitar que se limpien las filas.

Además, si usa cursores, no puede devolver las conexiones a un grupo de conexiones. Necesitará una conexión por cliente. Eso significa que se usan 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 cursor.

También existe la complejidad y la sobrecarga de administrar una configuración con estado basada en cursor en comparación con un enfoque de agrupación de conexiones sin estado con límite y desplazamiento. Debe hacer que los cursores de su aplicación caduquen después de un tiempo de espera o se enfrentará a un uso de recursos potencialmente ilimitado en el servidor, y debe realizar 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 puede ser la mejor solución. A menudo puede ser mejor buscar la clave principal en lugar de usar OFFSET , sin embargo.

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 se deje abierta una conexión a la base de datos?

Sí.

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

Sí, a menos que sean WITH HOLD , en cuyo caso consumen otros recursos de la base de datos.

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

Sí, como lo anterior debería explicar.