PostgreSQL:在其他客户端中查询速度慢10倍


问题内容

查看postgres服务器日志,我发现从Linux客户端或Windows客户端调用同一Postgres服务器上完全相同的查询会花费更长的时间(大约10倍)。

这些查询来自运行在具有4GB RAM的Linux机器和具有8GB
RAM的Windows机器上的Django应用程序。两种pyhon环境都具有psycopg2库2.4.4版,用于将请求发送到同一postgres服务器。

以下是Postgres服务器日志

Windows查询(随时间):

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执行(最快):

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

其他不需要从数据库中加载这么多项目的查询的性能几乎相同。

为什么客户之间的查询时差如此之大?

注意
:传输时间无关紧要,因为所有计算机都在同一个Intranet中。另外,当客户端请求来自运行postgresql服务器的同一Linux机器时,会看到较慢的时间。

注意2
:Psycopg2在Windows和Linux中的安装方式有所不同。在Windows中,我是从预打包的二进制文件中安装的,而在Linux中,我运行了“
pip install
psycopg2”,它依赖于系统上可用的postgresql安装。这会导致影响客户端性能的参数(例如’work_mem’参数)的值不同吗?


问题答案:

您可能需要检查慢速客户端是否进行SSL加密。默认情况下,它是在服务器上设置的,并且客户端已使用SSL支持进行编译时发生。

对于检索大量数据的查询,时间差很大。同样,某些Linux发行版(例如Debian /
Ubuntu)默认情况下已启用SSL,即使通过localhost进行TCP连接也是如此。

举例来说,这是一个查询的时差,该查询使用温暖的缓存检索重达64Mbytes的1,5M行。

没有加密:

$ psql“主机=本地主机dbname = mlists sslmode =禁用”
密码: 
psql(9.1.7,服务器9.1.9)
键入“帮助”以获得帮助。

mlists => \ timing
时间到了。
mlists => \ o / dev / null
mlists =>从邮件中选择主题;
时间: **1672.258毫秒**

使用加密:

$ psql“主机=本地主机dbname = mlists”
密码: 
psql(9.1.7,服务器9.1.9)
**SSL连接(密码:DHE-RSA-AES256-SHA,位:256)**
键入“帮助”以获得帮助。

mlists => \ o / dev / null
mlists => \ timing
时间到了。
mlists =>从邮件中选择主题;
时间: **7017.935毫秒**

要全局关闭它,可以SSL=off在中设置postgresql.conf

要针对特定​​范围的客户地址将其关闭pg_hba.conf,请hostnossl在第一个字段中的更通用host条目之前添加带有的条目。

要关闭客户端(是否关闭),取决于驱动程序如何公开sslmode连接参数。如果不是,则PGSSLMODE如果驱动程序在之上实现,则可以使用环境变量libpq

对于通过Unix域套接字(local)进行的连接,永远不要将SSL与它们一起使用。