2013-06-11 10 views
5

postgresサーバのログを見ると、LinuxクライアントまたはWindowsクライアントから呼び出されたときに、同じpostgresサーバで全く同じクエリがずっと時間がかかります(約10倍長くなります) 。Postgresql:別のクライアントでクエリが10倍遅い

クエリは、4GBのRAMを搭載したLinuxマシンと8GBのRAMを搭載したWindowsマシンで動作するDjangoアプリケーションから取得されます。両方のpyhon環境では、同じpostgresサーバーにリクエストを送信するpsycopg2ライブラリバージョン2.4.4があります。

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

Linuxのクエリ(はるかに長い):

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

はPSQLから直接実行する(

以下

はPostgresのサーバログ

(時間)窓のクエリです最速):

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

データベースから非常に多くのアイテムをロードする必要のない他のクエリは、ほとんど同じ性能を発揮します。

このクエリのクライアント間で大きな違いがあるのはなぜですか?

注::すべてのマシンが同じイントラネットにあるため、送信時間は関係ありません。また、クライアント要求がpostgresqlサーバが実行されているのと同じLinuxマシンから来た場合、遅い時間が表示されます。

注2:Psycopg2は、WindowsとLinuxではインストール方法が異なります。 Windowsでは、パッケージ化されたバイナリからインストールしましたが、Linuxでは、システムで利用可能なpostgresqlのインストールに依存する 'pip install psycopg2'を実行しました。これにより、クライアント側のパフォーマンスに影響するパラメータ(例: 'work_mem'パラメータ)の値が異なる可能性がありますか?

+0

暗闇の中でちょっと一息:おそらくPostgreSQLの内部キャッシングの問題でしょうか? SELECT文をLinuxから複数回、Windowsから複数回送信しようとしましたか?私は、平均時間が同じでなければならないと思います。 – mawimawi

+0

to mawimawi:これらの時間は一貫していません。私は、生産用djangoアプリケーションが開発(Windows)マシンよりもはるかに低速だったので、デバッグを開始しました。あなたが複数回走った場合、時間は同じです。 – mpaf

+1

ネットワークラグに関連する可能性があります。特に、サーバーから次のサーバーに大量のデータを送信している場合。サーバレベルでクエリを記録し、実際にPostgresでどれくらいの時間が費やされたかを確認します。ああ、それはまた、Pythonの実行時の違いかもしれない。 –

答えて

7

低速クライアントがSSL暗号化を行っているかどうかを確認したい場合があります。サーバー上でセットアップされ、クライアントがSSLサポートを使用してコンパイルされている場合は、デフォルトで発生します。

大量のデータを取得するクエリでは、時間の差が大きくなります。 Debian/UbuntuのようなLinuxディストリビューションの中には、localhostを使ったTCP接続の場合でも、デフォルトでSSLがオンになっているものがあります。

例として、暖かいキャッシュを使用して計量された合計64Mバイトの1,5M行を検索するクエリの時間差を次に示します。暗号化されずに

 
$ 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 

暗号化で:

 
$ 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 

は1つがpostgresql.confSSL=offを設定するかもしれませんが、グローバルにオフにします。

クライアントアドレスの特定の範囲でこれを無効にするには、より一般的なhostエントリの前に、最初のフィールドにpg_hba.confのエントリをhostnosslで追加します。

クライアント側がオフの場合は、ドライバがsslmode接続パラメータを公開する方法によって異なります。そうでなければ、ドライバがlibpqの上に実装されている場合は、PGSSLMODE環境変数を使用することができます。

Unixドメインソケット(local)を介した接続に関しては、SSLは使用されません。

+0

偉大な答え!私はテストして、あなたが正しいと思って、SSLはパフォーマンスに影響を与えていました。 WindowsとLinuxの両方で、実際にpostgresql.confでSSLを無効にしたとき、Windowsの時間は3秒から1.7秒に、Linuxの時間は22秒から1.5秒に短縮されました。だから両方がSSLを通過しているようですが、Linuxはそれにより影響を受けますか?あなたの答え、良い洞察に感謝します。 – mpaf

+0

@mpaf:喜んで助けます。 Linuxがより影響を受けているので、それ以上の調査をせずに説明するのは難しいです。より強力な暗号がLinux上で選択されるかもしれないが、それはちょうど投機である。 –

関連する問題