1

我有一个使用 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

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

4

3 回答 3

4

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

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

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

This difference between the plans of prepared and unprepared statements should go away in PostgreSQL 9.2. It's been a long-standing wart, but Tom Lane dealt with it for the up-coming release.

于 2012-07-11T12:55:56.630 回答
1

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

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

于 2012-07-11T08:38:17.420 回答
1

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

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

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

于 2012-07-11T08:40:27.997 回答