我已经回顾了类似问题See and clear Postgres caches/buffers?,但所有答案都集中在数据缓冲区上,自2010年以来Postgresql已经发生了很大变化。
与该问题的OP不同,我不是在计算性能时寻找一致的行为,我正在寻找适应性行为,因为数据库随着时间的推移而变化。
在我的应用程序中,在作业执行开始时,工作表中的行为空。查询运行得非常快,但随着时间的推移,性能会下降,因为准备好的语句没有使用理想的访问路径(它们是在表空的时候准备的 - doh!)。由于作业的典型执行最终将覆盖几亿行,因此我需要最小化所有开销并定期运行统计信息以获得最佳访问路径。
在SQLServer中,可以定期调用update statistics
和DBCC FreeProccache
,并自动重新准备准备好的语句以使用新的访问路径。
编辑: FreeProcCache :在SQLServer中,预准备语句作为存储过程实现。 FreeProcCache擦除已编译的存储过程,以便在下次调用时重新编译它们,新的访问路径立即生效。
编辑: postgresql管理预准备语句的详细信息:Postgresql推迟准备直到第一次调用EXECUTE
,并在第5次执行后缓存准备结果。缓存后,计划将被修复,直到会话结束或准备好的语句被DEALLOCATE
释放。关闭JDBC对象不会调用DEALLOCATE
,作为支持打开/读取/关闭编程的优化,就像许多Web应用程序显示一样。
有没有办法在运行ANALYZE
后强制(编辑) JDBC 预处理语句重新编译,(编辑),这样它会使用最新的统计信息吗?
编辑:我正在使用JDBC PreparedStatement
来准备和执行针对数据库和Postgres JDBC驱动程序的查询。
答案 0 :(得分:0)
Postgresql更新统计信息的方式是ANALYZE。在VACUUM
运行后也会自动执行此操作(从VACUUM
释放引用,并截断空页面,我会想象您的FreeProccache
)。
如果启用autovacuum(默认值),则ANALYZE将根据autovacuum cadence自动运行。
您不需要重新编译"在大多数情况下,准备好的语句用于获取新统计信息,因为它将在每个EXECUTE期间重新计划,并且参数化的预准备语句将根据参数值和更新的统计信息进行重新计划。编辑:边缘案例described是查询计划者决定强制执行"通用计划的地方{#3}}。因为特定计划的估计成本超过了这种"通用计划的成本"经过5次计划执行。
编辑:
如果你确实达到了这个边缘情况,你可以“放弃”#34;准备好的陈述通过DEALLOCATE
(然后是重新PREPARE
)。
您可能想在EXECUTE之前尝试ANALYZE,但这不能保证更好的性能......
答案 1 :(得分:0)
请确保您确实要重新准备语句。您可能只是想不时关闭数据库连接,以使语句“从头开始”进行准备
如果您真的了解自己在做什么(可能有您所描述的有效原因),则可以发出DEALLOCATE ALL
语句(这是PostgreSQL特定的语句,用于释放所有准备好的语句)。 pgjdbc的最新版本(自9.4.1210,2016-09-07起)可以很好地处理并在以后使用时重新准备语句