2013-06-11 31 views
5

Guardando il log del server postgres, vedo che la stessa esatta query sullo stesso server postgres richiede molto più tempo (circa 10 volte di più) quando viene richiamata da un client Linux o da un client Windows .Postgresql: query 10 volte più lenta in un client diverso

Le query provengono da un'applicazione Django in esecuzione su una macchina Linux con 4 GB di RAM e su una macchina Windows con 8 GB di RAM. Entrambi gli ambienti pyhon dispongono della versione 2.4.4 della libreria psycopg2 per inviare richieste allo stesso server postgres.

Qui di seguito sono i registri postgres del server

la query finestre (con il tempo):

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 query linux (molto più lungo):

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') 

esecuzione direttamente dal psql (la più veloce):

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'); 

Altre query che non richiedono il caricamento di così tanti elementi dal database sono quasi identiche.

Perché così grandi differenze di tempo tra i clienti per questa query?

Nota: i tempi di trasmissione non sono rilevanti, poiché tutte le macchine si trovano nella stessa intranet. Inoltre, i tempi più lenti vengono visualizzati quando la richiesta del client proviene dalla stessa macchina Linux su cui è in esecuzione il server postgresql.

Note2: Psycopg2 è stato installato in modo diverso in Windows e Linux. Mentre in Windows l'ho installato da un binario preconfezionato, in Linux ho eseguito "pip install psycopg2" che si basa su un'installazione postgresql disponibile sul sistema. Ciò potrebbe comportare valori diversi per i parametri che influenzano le prestazioni sul lato client (ad esempio il parametro "work_mem")?

+0

Solo uno sparo al buio: forse si tratta di un problema di caching interno di PostgreSQL? Hai provato a inviare l'istruzione SELECT più volte da Linux e anche più volte da Windows? Immagino che il tempo medio dovrebbe essere lo stesso allora. – mawimawi

+0

to mawimawi: No, questi tempi sono coerenti, ho iniziato il debugging perché la mia app di django di produzione era molto più lenta rispetto alla macchina di sviluppo (Windows). I tempi sono gli stessi se si esegue più volte. – mpaf

+1

Potrebbe essere correlato ai ritardi di rete. Soprattutto se stai trasmettendo grandi quantità di dati da un server all'altro. Registra la query a livello di server, per vedere quanto tempo è effettivamente speso in Postgres. Oh, potrebbero anche esserci differenze nel tempo di esecuzione in python, ad es. creazione di oggetti, ecc. –

risposta

7

È possibile controllare se il client lento esegue la crittografia SSL o meno. Succede di default quando è impostato sul server e il client è stato compilato con il supporto SSL.

Per le query che recuperano grandi quantità di dati, la differenza di orario è significativa. Anche alcune distribuzioni Linux come Debian/Ubuntu hanno SSL attivo per impostazione predefinita, anche per le connessioni TCP tramite localhost.

Ad esempio, ecco la differenza di tempo per una query che richiama le righe da 1,5 M per un totale di 64 Mbyte, con una cache calda.

Senza crittografia:

 
$ psql "host=localhost dbname=mlists sslmode=disable" 
Password: 
psql (9.1.7, server 9.1.9) 
Type "help" for help. 

mlists=> \timing 
Timing is on. 
mlists=> \o /dev/null 
mlists=> select subject from mail; 
Time: 1672.258 ms 

Con crittografia:

 
$ psql "host=localhost dbname=mlists" 
Password: 
psql (9.1.7, server 9.1.9) 
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) 
Type "help" for help. 

mlists=> \o /dev/null 
mlists=> \timing 
Timing is on. 
mlists=> select subject from mail; 
Time: 7017.935 ms 

di spegnerlo globalmente, si potrebbe impostare SSL=off in postgresql.conf.

Per disattivarlo per intervalli specifici di indirizzi client, aggiungere voci in pg_hba.conf con hostnossl nel primo campo prima delle voci più generiche host.

Per disattivare se lato client, dipende da come il driver espone il parametro di connessione sslmode. In caso contrario, è possibile utilizzare la variabile di ambiente PGSSLMODE se il driver è implementato su libpq.

Per quanto riguarda le connessioni tramite socket di dominio Unix (local), SSL non viene mai utilizzato con esse.

+0

Ottima risposta! Ho provato e avevi ragione, SSL stava influenzando le prestazioni. Sia per Windows che per Linux in realtà, quando ho disabilitato SSL in postgresql.conf, il tempo di Windows passava da 3 a 1.7 s e tempo di Linux da 22 a 1.5 s! Quindi sembra che entrambi stessero attraversando SSL ma Linux ne ha risentito maggiormente? Grazie mille per la tua risposta, buona intuizione. – mpaf

+0

@mpaf: contento che aiuti. Dal momento che Linux è più interessato, è difficile spiegarlo senza ulteriori indagini. Potrebbe essere che un codice più potente venga selezionato su Linux, ma questa è solo una speculazione. –

Problemi correlati