Postgresql: consulta 10x más lenta en un cliente diferente

Al mirar el registro del servidor de Postgres, veo que la misma consulta exacta en el mismo servidor de Postgres toma mucho más tiempo (aproximadamente 10 veces más) cuando se invoca desde un cliente Linux o desde un cliente Windows.

Las consultas provienen de una aplicación Django que se ejecuta en una máquina Linux con 4GB de RAM y en una máquina de Windows con 8GB de RAM. Ambos entornos de Pyhon tienen la biblioteca psycopg2 versión 2.4.4 para enviar solicitudes al mismo servidor de Postgres.

A continuación se muestran los registros del servidor de Postgres

La consulta de windows (con tiempo):

2013-06-11 12:12:19 EEST [unknown] 10.1.3.152(56895) mferreiraLOG: duration: 3207.195 ms statement: SELECT "autotests_tracerperformance"."id", "autotests_tracerperformance"."date", "autotests_tracerperformance"."video_id", "autotests_tracerperformance"."revision_id", "autotests_tracerperformance"."computer_id", "autotests_tracerperformance"."probe", "autotests_tracerperformance"."time_tostart", "autotests_tracerperformance"."hang_atstart", "autotests_tracerperformance"."time_tohang", "autotests_tracerperformance"."hang", "autotests_tracerperformance"."crash", "autotests_tracerperformance"."stacktrace", "autotests_tracerperformance"."framemax", "autotests_tracerperformance"."maxtime", "autotests_tracerperformance"."avgtime" FROM "autotests_tracerperformance" INNER JOIN "revisions" ON ("autotests_tracerperformance"."revision_id" = "revisions"."id") WHERE ("autotests_tracerperformance"."computer_id" = 61 AND "revisions"."repo" = 'Trunk' ) 

La consulta de linux (mucho más larga):

 2013-06-11 12:12:56 EEST [unknown] 10.1.3.154(35325) mferreiraLOG: duration: 22191.773 ms statement: SELECT "autotests_tracerperformance"."id", "autotests_tracerperformance"."date", "autotests_tracerperformance"."video_id", "autotests_tracerperformance"."revision_id", "autotests_tracerperformance"."computer_id", "autotests_tracerperformance"."probe", "autotests_tracerperformance"."time_tostart", "autotests_tracerperformance"."hang_atstart", "autotests_tracerperformance"."time_tohang", "autotests_tracerperformance"."hang", "autotests_tracerperformance"."crash", "autotests_tracerperformance"."stacktrace", "autotests_tracerperformance"."framemax", "autotests_tracerperformance"."maxtime", "autotests_tracerperformance"."avgtime" FROM "autotests_tracerperformance" INNER JOIN "revisions" ON ("autotests_tracerperformance"."revision_id" = "revisions"."id") WHERE ("autotests_tracerperformance"."computer_id" = 61 AND "revisions"."repo" = 'Trunk' ) 

ejecutando directamente desde psql (el más rápido):

 2013-06-11 12:19:06 EEST psql [local] mferreiraLOG: duration: 1332.902 ms statement: SELECT "autotests_tracerperformance"."id", "autotests_tracerperformance"."date", "autotests_tracerperformance"."video_id", "autotests_tracerperformance"."revision_id", "autotests_tracerperformance"."computer_id", "autotests_tracerperformance"."probe", "autotests_tracerperformance"."time_tostart", "autotests_tracerperformance"."hang_atstart", "autotests_tracerperformance"."time_tohang", "autotests_tracerperformance"."hang", "autotests_tracerperformance"."crash", "autotests_tracerperformance"."stacktrace", "autotests_tracerperformance"."framemax", "autotests_tracerperformance"."maxtime", "autotests_tracerperformance"."avgtime" FROM "autotests_tracerperformance" INNER JOIN "revisions" ON ("autotests_tracerperformance"."revision_id" = "revisions"."id") WHERE ("autotests_tracerperformance"."computer_id" = 61 AND "revisions"."repo" = 'Trunk' ); 

Otras consultas que no necesitan cargar tantos elementos de la base de datos están realizando casi lo mismo.

¿Por qué diferencias tan grandes entre clientes para esta consulta?

Nota : Los tiempos de transmisión no son relevantes, ya que todas las máquinas están en la misma intranet. Además, los tiempos más lentos se ven cuando la solicitud del cliente proviene de la misma máquina Linux donde se está ejecutando el servidor postgresql.

Nota2 : Psycopg2 se instaló de manera diferente en Windows y Linux. Mientras que en Windows lo instalé desde un binario preempaquetado, en Linux ejecuté ‘pip install psycopg2’ que se basa en una instalación postgresql disponible en el sistema. ¿Podría esto resultar en diferentes valores para los parámetros que afectan el rendimiento en el lado del cliente (por ejemplo, el parámetro ‘work_mem’)?

Es posible que desee comprobar si el cliente lento realiza el cifrado SSL o no. Ocurre de forma predeterminada cuando se configura en el servidor y el cliente se ha comstackdo con soporte SSL.

Para consultas que recuperan grandes cantidades de datos, la diferencia de tiempo es significativa. También algunas distribuciones de Linux como Debian / Ubuntu tienen SSL activado de forma predeterminada, incluso para conexiones TCP a través de localhost.

Como ejemplo, aquí está la diferencia de tiempo para una consulta que recupera filas de 1,5M que pesan un total de 64 Mbytes, con un caché cálido.

Sin cifrado:

 $ psql "host = localhost dbname = mlists sslmode = disable"
 Contraseña: 
 psql (9.1.7, servidor 9.1.9)
 Escriba "ayuda" para ayuda.

 mlists => \ timing
 El tiempo está en marcha.
 mlists => \ o / dev / null
 mlists => seleccionar asunto del correo;
 Tiempo: 1672.258 ms

Con cifrado:

 $ psql "host = localhost dbname = mlists"
 Contraseña: 
 psql (9.1.7, servidor 9.1.9)
 Conexión SSL (cifrado: DHE-RSA-AES256-SHA, bits: 256)
 Escriba "ayuda" para ayuda.

 mlists => \ o / dev / null
 mlists => \ timing
 El tiempo está en marcha.
 mlists => seleccionar asunto del correo;
 Tiempo: 7017.935 ms

Para desactivarlo globalmente, uno puede configurar SSL=off en postgresql.conf .

Para desactivarlo para rangos específicos de direcciones de clientes, agregue entradas en pg_hba.conf con hostnossl en el primer campo antes de las entradas de host más genéricas.

Para desactivar el lado del cliente, depende de cómo el controlador expone el parámetro de conexión sslmode . Si no es así, la variable de entorno PGSSLMODE se puede usar si el controlador se implementa sobre libpq .

En cuanto a las conexiones a través de sockets de dominio Unix ( local ), SSL nunca se usa con ellos.