【问题标题】:Postgresql: Query 10x slower in a different clientPostgresql:在不同的客户端中查询慢 10 倍
【发布时间】:2013-06-07 02:41:00
【问题描述】:

查看 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”参数)?

【问题讨论】:

  • 只是在黑暗中拍摄:可能是 PostgreSQL 内部缓存问题?您是否尝试从 Linux 多次提交 SELECT 语句,也多次从 Windows 提交?我想那时平均时间应该是一样的。
  • to mawimawi:不,这些时间是一致的,我开始调试这个,因为我的生产 django 应用程序比开发(Windows)机器慢得多。如果你跑多次,时间是一样的。
  • 可能与网络延迟有关。特别是如果您将大量数据从服务器传输到下一个服务器。在服务器级别记录查询,以查看在 Postgres 中实际花费了多少时间。哦,这也可能是python中的执行时间差异,例如创建对象等。
  • 致丹尼斯:不是真的,我测试了在 postgresql 服务器所在的同一台机器上运行 django 应用程序 - 它比在具有 Windows 客户端的另一台机器上运行的 django 应用程序要多 10 倍。它似乎与客户端配置有关。所有服务器都是同一个本地 Intranet 的一部分,这并不重要 - 我认为 postgresql 日志显示在 postgres 服务器中运行的时间并且没有考虑数据传输(?)
  • 我同意 Denis 的观点,它看起来像网络问题 - 或 Linux 站网卡问题。

标签: python django postgresql psycopg2


【解决方案1】:

您可能想检查慢速客户端是否进行 SSL 加密。当它在服务器上设置并且客户端已经编译了 SSL 支持时,默认情况下会发生这种情况。

对于检索大量数据的查询,时间差异很大。 此外,一些 Linux 发行版(如 Debian/Ubuntu)默认启用 SSL,即使是通过 localhost 的 TCP 连接也是如此。

例如,以下是使用热缓存检索 1,5M 行总重为 64Mbytes 的查询的时间差。

没有加密:

$ psql "host=localhost dbname=mlist sslmode=disable" 密码: psql(9.1.7,服务器 9.1.9) 键入“帮助”以获得帮助。 mlists=> \计时 定时开启。 mlists=> \o /dev/null mlists=> 从邮件中选择主题; 时间:1672.258 毫秒

加密:

$ psql "host=localhost dbname=mlist" 密码: psql(9.1.7,服务器 9.1.9) SSL 连接(密码:DHE-RSA-AES256-SHA,位:256) 键入“帮助”以获得帮助。 mlists=> \o /dev/null mlists=> \计时 定时开启。 mlists=> 从邮件中选择主题; 时间:7017.935 毫秒

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

要为特定范围的客户端地址关闭它,请在更通用的 host 条目之前的第一个字段中添加 pg_hba.confhostnossl 条目。

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

至于通过 Unix 域套接字 (local) 的连接,SSL 从不与它们一起使用。

【讨论】:

  • 很好的答案!我测试过,你是对的,SSL 正在影响性能。实际上,对于 Windows 和 Linux,当我在 postgresql.conf 中禁用 SSL 时,Windows 时间从 3 秒下降到 1.7 秒,Linux 时间从 22 秒下降到 1.5 秒!所以看起来两者都在通过 SSL 但 Linux 更受它的影响?非常感谢您的回答,很好的见解。
  • @mpaf:很高兴它有帮助。至于 Linux 受到的影响更大,没有更多调查就很难解释。可能是在 Linux 上选择了更强大的密码,但这只是猜测。
猜你喜欢
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 2011-01-02
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 2021-03-15
相关资源
最近更新 更多