postgresql查询的大ResultSet

时间:2009-05-05 21:59:37

标签: java spring postgresql jdbc spring-jdbc

我正在对postgresql数据库中的表运行查询。数据库位于远程计算机上。该表包含大约30个使用postgresql partitioning capability的子表。

查询将返回一个大的结果集,大约180万行。

在我的代码中,我使用spring jdbc支持,方法JdbcTemplate.query,但我的RowCallbackHandler没有被调用。

我最好的猜测是postgresql jdbc驱动程序(我使用版本8.3-603.jdbc4)在调用我的代码之前将结果累积到内存中。我认为fetchSize configuration可以控制它,但我尝试了它并没有任何改变。我这样做是作为postgresql手册recomended

当我使用Oracle XE时,此查询工作正常。但我正在尝试迁移到postgresql,因为分区功能在Oracle XE中不可用。

我的环境:

  • Postgresql 8.3
  • Windows Server 2008 Enterprise 64位
  • JRE 1.6 64位
  • Spring 2.5.6
  • Postgresql JDBC Driver 8.3-603

4 个答案:

答案 0 :(得分:4)

为了使用游标检索数据,除了设置提取大小外,还必须将ResultSet类型设置为ResultSet.TYPE_FORWARD_ONLY(默认值)并自动提交为false。这是在您链接到的文档中引用的,但您没有明确提到您已执行这些步骤。

小心PostgreSQL的分区方案。它确实与优化器一起发生了非常可怕的事情,并且可能导致大量性能问题,而不应该存在(取决于您的数据的具体情况)。无论如何,你的行只有1.8M行吗?没有理由因为它被适当地编入索引而需要根据大小进行分区。

答案 1 :(得分:2)

我打赌你的应用程序中没有一个客户端同时需要1.8M行。你应该想出一种合理的方法将结果分成更小的部分,并让用户有机会迭代它们。

这就是谷歌所做的。当您进行搜索时,可能会有数百万次点击,但它们一次返回25页,并且您可以在第一页中找到所需内容。

如果它不是客户端,并且结果正在以某种方式进行按摩,我建议让数据库处理所有这些行并简单地返回结果。返回1.8M行只是为了在中间层进行计算是没有意义的。

如果这些都不适用,那你就有了一个真正的问题。是时候重新思考它了。

在阅读后面的回复之后,我觉得这更像是一种报告解决方案,应该是批量处理或实时计算并存储在不属于交易系统的表中。没有办法将1.8M行带到中间层来计算移动平均线可以扩展。

我建议您自己重新定位 - 开始将其视为报告解决方案。

答案 2 :(得分:2)

fetchSize属性的工作方式与postgres manual

中所述的相同

我的错误是我将auto commit = false设置为来自连接池的连接,该连接池不是预准备语句使用的连接。

感谢所有反馈。

答案 3 :(得分:0)

我做了以上所有事情,但我需要最后一部分:确保调用包含在事务中并将事务设置为只读,这样就不需要回滚状态。

我添加了这个:@Transactional(readOnly = true)

干杯。