Además de guardar la sobrecarga de la conexión & desconectar donde se hace esto en cada solicitud, un grupo de conexión puede canalizar un gran número de conexiones de cliente a un número reducido de conexiones de base de datos reales. En PostgreSQL, la cantidad óptima de conexiones de bases de datos activas suele ser algo cercano ((2 * core_count) + effective_spindle_count). Por encima de este número, tanto el rendimiento como la latencia empeoran.
A veces la gente dirá "Quiero admitir 2000 usuarios, con un tiempo de respuesta rápido". Está prácticamente garantizado que si intentas hacer eso con 2000 conexiones de bases de datos reales, el rendimiento será horrible. Si tiene una máquina con cuatro procesadores de cuatro núcleos y el conjunto de datos activos está completamente en caché, verá un rendimiento mucho mejor para esos 2000 usuarios al canalizar las solicitudes a través de aproximadamente 35 conexiones de bases de datos.
Para entender por qué eso es cierto, este experimento mental debería ayudar. Considere una máquina hipotética de servidor de base de datos con solo un recurso para compartir: un solo núcleo. Este núcleo dividirá el tiempo en partes iguales entre todas las solicitudes concurrentes sin sobrecarga. Digamos que 100 solicitudes vienen todas en el mismo momento, cada una de las cuales necesita un segundo de tiempo de CPU. El núcleo funciona en todos ellos, cortando el tiempo entre ellos hasta que todos terminan 100 segundos después. Ahora considere lo que sucede si coloca un grupo de conexiones al frente que aceptará 100 conexiones de clientes, pero haga solo una solicitud a la vez al servidor de la base de datos, colocando todas las solicitudes que lleguen mientras la conexión esté ocupada en una cola. Ahora, cuando llegan 100 solicitudes al mismo tiempo, un cliente recibe una respuesta en 1 segundo; otro obtiene una respuesta en 2 segundos, y el último cliente recibe una respuesta en 100 segundos. Nadie tuvo que esperar más tiempo para obtener una respuesta, el rendimiento es el mismo, pero la latencia promedio es de 50,5 segundos en lugar de 100 segundos.
Un servidor de base de datos real tiene más recursos que se pueden usar en paralelo, pero el mismo principio es que, una vez que están saturados, solo hace daño agregando más solicitudes de bases de datos simultáneas. En realidad es peor que el ejemplo, porque con más tareas tiene más conmutadores de tareas, mayor contención de bloqueos y caché, contención de líneas de caché L2 y L3 y muchos otros problemas que reducen el rendimiento y la latencia. Además de eso, mientras que una configuración alta work_mem
puede ayudar a una consulta de varias maneras, esa configuración es el límite por nodo de plan para cada conexión, por lo que con un gran número de conexiones debe dejar esto muy pequeño para evitar limpiar el caché o incluso provocar el intercambio, lo que conduce a planes más lentos o cosas tales como que las tablas hash se propaguen al disco. Algunos productos de bases de datos construyen efectivamente un grupo de conexiones en el servidor, pero la comunidad PostgreSQL ha adoptado la posición de que dado que la mejor conexión se realiza más cerca del software del cliente, dejarán que los usuarios lo administren. La mayoría de los usuarios compartidos tendrán alguna manera de limitar las conexiones de la base de datos a un número difícil, al mismo tiempo que permiten más solicitudes concurrentes de clientes que eso, poniéndolos en cola según sea necesario. Esto es lo que desea, y debe hacerse en una base transaccional, no por estado o conexión.
También existe la posibilidad de que su modelo de base de datos no coincida con las consultas que le está ejecutando. Normalmente, la sobrecarga de red es muy pequeña en comparación con el trabajo necesario para obtener bloques de datos del disco, también: esto no cuesta rendimiento, solo latencia. (excepto tal vez para el caso de conexiones/desconexiones muy frecuentes) – wildplasser