我在Play Framework 1.2.4上使用Hibernate(默认的C3P0连接池)和PostgreSQL数据库(9.1)编写了一个应用程序。
最近我在postgresql.conf中启用了慢速查询记录(> = 100毫秒)并发现了一些问题。
但是当我尝试分析和优化一个特定的查询时,我发现它在psql(0.5 - 1 ms)中比在日志中的200-250 ms快得多。其他查询也发生了同样的事情。
应用程序和数据库服务器在同一台计算机上运行,并使用localhost接口进行通信。
JDBC驱动程序 - postgresql-9.0-801.jdbc4
我想知道可能出现什么问题,因为日志中的查询持续时间只考虑数据库处理时间,不包括网络周转等外部因素。
答案 0 :(得分:4)
可能性1:如果偶尔或突发发生慢查询,则可能是检查点活动。启用检查点日志记录(log_checkpoints = on
),确保日志级别(log_min_messages
)为“信息”或更低,并查看出现的情况。需要很长时间或经常发生的检查点建议你可能需要一些检查点/ WAL和bgwriter调整。如果相同的陈述总是很慢而其他陈述总是表现良好,那么这可能不是原因。
可能性2:您的查询计划有所不同,因为您直接在psql
中运行它们,而Hibernate,通过PgJDBC,至少有时会执行PREPARE
和EXECUTE
(在协议级别,所以你不会看到实际的声明)。为此,请将查询效果与PREPARE test_query(...) AS SELECT ...
和EXPLAIN ANALYZE EXECUTE test_query(...)
进行比较。 PREPARE中的参数是位置参数的类型名称($ 1,$ 2等); EXECUTE中的参数是值。
如果准备好的计划与一次性计划不同,您可以通过连接参数设置PgJDBC's prepare threshold,告诉它永远不要使用服务器端预处理语句。
准备和未准备陈述的计划之间存在差异should go away in PostgreSQL 9.2。这是一个长期存在的疣,但是汤姆·莱恩(Tom Lane)为即将发布的版本处理了它。
答案 1 :(得分:1)
有几个可能的原因。首先,如果数据库在慢速查询执行时非常繁忙,则查询可能会更慢。因此,您可能需要在此时观察操作系统的负载以供将来分析。
其次,sql的历史计划可能与当前的会话计划不同。因此,您可能需要安装auto_explain才能查看慢速查询的实际计划。
答案 2 :(得分:1)
如果不了解系统的所有细节,很难肯定地说,但我可以想到几种可能性:
关键是你是正确的,查询持续时间不受哪个库或应用程序调用它的影响,因此差异必须来自其他东西。继续看,祝你好运!