postgresql查询的大ResultSet

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

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

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

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

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

我的环境:

  • Postgresql 8.3
  • Windows Server 2008 Enterprise 64位
  • JRE 1.6 64位
  • spring2.5.6
  • Postgresql JDBC Driver 8.3-603

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

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

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

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

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

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

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

我建议自己重新定位 – 开始考虑将其作为报告解决方案。

fetchSize属性的工作方式与postgres手册中描述的相同。

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

感谢所有的反馈。

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

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

干杯。