PostgreSQL。日志文件中的慢查询在 psql 中很快

Posted

技术标签:

【中文标题】PostgreSQL。日志文件中的慢查询在 psql 中很快【英文标题】:PostgreSQL. Slow queries in log file are fast in psql 【发布时间】:2012-07-11 08:14:04 【问题描述】:

我有一个使用 Hibernate(默认 C3P0 连接池)和 PostgreSQL 数据库 (9.1) 在 Play Framework 1.2.4 上编写的应用程序。

最近我在 postgresql.conf 中开启了慢查询日志 (>= 100 ms),发现了一些问题。

但是当我尝试分析和优化一个特定查询时,我发现它在 psql (0.5 - 1 ms) 中的速度比日志中的 200-250 ms 快得多。其他查询也发生了同样的事情。

应用程序和数据库服务器在同一台机器上运行,并使用 localhost 接口进行通信。

JDBC 驱动程序 - postgresql-9.0-801.jdbc4

我想知道可能出了什么问题,因为在计算日志中的查询持续时间时,只考虑了数据库处理时间,不包括网络周转等外部因素。

【问题讨论】:

【参考方案1】:

可能性一:如果慢查询偶尔出现或突发,可能是检查点活动。启用检查点日志记录 (log_checkpoints = on),确保日志级别 (log_min_messages) 为“信息”或更低,然后查看结果。需要很长时间或经常发生的检查点表明您可能需要一些检查点/WAL 和 bgwriter 调整。如果相同的语句总是很慢而其他语句总是执行良好,这不太可能是原因。

可能性 2:您的查询计划不同,因为您直接在 psql 中运行它们,而 Hibernate 通过 PgJDBC 至少有时会执行 PREPAREEXECUTE(在协议级别,所以您赢了'看不到实际的陈述)。为此,将查询性能与PREPARE test_query(...) AS SELECT ... 然后EXPLAIN ANALYZE EXECUTE test_query(...) 进行比较。 PREPARE 中的参数是位置参数的类型名称($1、$2 等); EXECUTE 中的参数是值。

如果prepared plan和one-off plan不同,可以通过连接参数设置PgJDBC's prepare threshold,告诉它永远不要使用服务器端prepared statements。

准备好的和未准备好的语句计划之间的差异should go away in PostgreSQL 9.2。这是一个长期存在的缺陷,但 Tom Lane 为即将发布的版本处理了它。

【讨论】:

谢谢!有用的提示。我会试试的。 对此***.com/questions/36786949/…的任何见解【参考方案2】:

如果不了解系统的所有细节,很难确定,但我可以想到几种可能性:

查询结果被缓存。如果您在短时间内运行相同的查询两次,第二次执行几乎总是会更快地完成。为了这个目的,PostgreSQL 维护了一个最近检索到的数据的缓存。如果您从日志尾部提取查询并立即执行它们,这可能是正在发生的事情。 其他进程正在干扰。查询的执行时间因系统中发生的其他情况而异。如果在您网站的高峰时段,当有很多用户连接时,查询需要 100 毫秒,但当您在深夜再次尝试查询时,查询只需要 1 毫秒,这可能是正在发生的事情。

关键是您是正确的,查询持续时间不受哪个库或应用程序调用它的影响,因此差异必须来自其他东西。继续寻找,祝你好运!

【讨论】:

好吧。考虑到 htop 和 top 输出,数据库服务器根本没有过载。我有 2 个 proc 框。平均负载接近 0.9 - 1,这是低的。无论如何,谢谢你的提示。 是的,这些只是显而易见的答案,但我知道你知道你在做什么。 franc 的 auto_explain 建议听起来不错。【参考方案3】:

有几个可能的原因。首先,如果执行慢查询时数据库非常繁忙,则查询可能会更慢。因此,您可能需要观察当时操作系统的负载以供将来分析。

第二个sql的历史计划可能与当前会话计划不同。所以你可能需要安装auto_explain才能看到慢查询的实际方案。

【讨论】:

完全同意,采样load average 以及慢查询日志以获得完整的图片。

以上是关于PostgreSQL。日志文件中的慢查询在 psql 中很快的主要内容,如果未能解决你的问题,请参考以下文章

一次PostgreSQL行估算偏差导致的慢查询分析

phpMyAdmin中的慢查询但Mysql慢查询日志文件中没有[关闭]

特定 PostgreSQL 客户端/版本中的慢查询

使用MySQL的慢查询日志找到低效的SQL语句

Django 慢查询:将 django 过滤语句连接到数据库日志中的慢查询

markdown 删除Mysql中的慢查询日志