2013-06-11 4 views
5

Mit Blick auf das Postgres-Serverprotokoll, sehe ich, dass die gleiche Abfrage auf dem gleichen Postgres Server viel länger dauert (etwa 10x länger) beim Aufruf von einem Linux-Client oder von einem Windows-Client .Postgresql: Abfrage 10x langsamer in einem anderen Client

Die Abfragen stammen von einer Django-Anwendung, die auf einem Linux-Rechner mit 4 GB RAM und auf einem Windows-Rechner mit 8 GB RAM ausgeführt wird. Beide pyhon-Umgebungen haben die psycopg2-Bibliothek Version 2.4.4, um Anfragen an den gleichen postgres-Server zu senden.

Im Folgenden sind die Postgres-Server-Logs

Die Abfragefenster (mit der Zeit):

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

Die Linux-Abfrage (viel mehr):

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

gerade von psql Ausführung (die am schnellsten):

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

Andere Abfragen, bei denen nicht so viele Elemente aus der Datenbank geladen werden müssen, funktionieren fast gleich.

Warum so große Zeit Unterschiede zwischen Clients für diese Abfrage?

Hinweis: Übertragungszeiten sind nicht relevant, da sich alle Maschinen im selben Intranet befinden. Die langsameren Zeiten werden auch angezeigt, wenn die Clientanforderung von demselben Linux-Computer stammt, auf dem auch der postgresql-Server ausgeführt wird.

Hinweis2: Psycopg2 wurde in Windows und Linux anders installiert. Während ich es in Windows aus einer vorinstallierten Binärdatei installierte, habe ich in Linux 'pip install psycopg2' ausgeführt, das auf einer postgresql-Installation beruht, die auf dem System verfügbar ist. Könnte dies zu unterschiedlichen Werten für Parameter führen, die die Leistung auf der Clientseite beeinflussen (z. B. Parameter 'work_mem')?

+0

Nur ein Schuss in die Dunkelheit: Vielleicht ist es ein PostgreSQL internes Caching-Problem? Haben Sie versucht, die SELECT-Anweisung mehrfach von Linux und auch mehrfach von Windows zu senden? Ich würde mir vorstellen, dass die durchschnittliche Zeit dann gleich sein sollte. – mawimawi

+0

zu mawimawi: Nein diese Zeiten sind konsistent, ich begann zu debuggen dies als meine Produktion Django App war viel langsamer als in der Entwicklung (Windows) Maschine. Die Zeiten sind gleich, wenn Sie mehrere Male laufen. – mpaf

+1

Es könnte mit Netzwerkverzögerungen zusammenhängen. Vor allem, wenn Sie große Datenmengen von einem Server zum nächsten übertragen. Protokollieren Sie die Abfrage auf Serverebene, um zu sehen, wie viel Zeit tatsächlich in Postgres verbracht wurde. Oh, es könnten auch Ausführungszeitunterschiede in Python sein, z. Erstellen von Objekten usw. –

Antwort

7

Sie können überprüfen, ob der langsame Client SSL-Verschlüsselung durchführt oder nicht. Es passiert standardmäßig, wenn es auf dem Server eingerichtet ist und der Client mit SSL-Unterstützung kompiliert wurde.

Bei Abfragen, die große Datenmengen abrufen, ist der Zeitunterschied signifikant. Auch bei einigen Linux-Distributionen wie Debian/Ubuntu ist SSL standardmäßig aktiviert, selbst bei TCP-Verbindungen über localhost.

Als Beispiel, hier ist der Zeitunterschied für eine Abfrage Abrufen von 1,5 Millionen Zeilen mit insgesamt 64 MB, mit einem warmen Cache.

Ohne Verschlüsselung:

 
$ 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 

Mit Verschlüsselung:

 
$ 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 

Zum Ausschalten global, ein SSL=off in postgresql.conf gesetzt könnten.

Um es für bestimmte Bereiche von Clientadressen zu deaktivieren, fügen Sie Einträge in pg_hba.conf mit hostnossl in das erste Feld vor den generischen host Einträge.

Um aus der Client-Seite auszuschalten, hängt es davon ab, wie der Treiber den sslmode Verbindungsparameter verfügbar macht. Wenn dies nicht der Fall ist, kann die Umgebungsvariable PGSSLMODE verwendet werden, wenn der Treiber über libpq implementiert wird.

Wie für Verbindungen über Unix-Domain-Sockets (local), SSL wird nie mit ihnen verwendet.

+0

Große Antwort! Ich habe getestet und Sie hatten Recht, SSL hat die Leistung beeinträchtigt. Sowohl für Windows als auch für Linux, als ich SSL in postgresql.conf deaktiviert habe, ging die Windows-Zeit von 3s auf 1,7s und die Linux-Zeit von 22s auf 1,5s runter! Es scheint also, beide durch SSL gegangen, aber Linux mehr davon betroffen? Vielen Dank für Ihre Antwort, gute Einsicht. – mpaf

+0

@mpaf: froh, dass es hilft. Da Linux stärker betroffen ist, ist es ohne weitere Untersuchungen schwer zu erklären. Es könnte sein, dass eine stärkere Chiffre unter Linux ausgewählt wird, aber das ist nur Spekulation. –

Verwandte Themen