6

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

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

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

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

当我使用 Oracle XE 时,此查询运行良好。但是我正在尝试迁移到 postgresql,因为分区功能在 Oracle XE 中不可用。

我的环境:

  • PostgreSQL 8.3
  • Windows Server 2008 企业版 64 位
  • JRE 1.6 64 位
  • 春天 2.5.6
  • Postgresql JDBC 驱动程序 8.3-603
4

4 回答 4

6

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

小心 PostgreSQL 的分区方案。它确实对优化器做了非常可怕的事情,并且可能会导致不应该出现的大量性能问题(取决于您的数据的具体情况)。无论如何,您的行只有 180 万行吗?鉴于它已被适当索引,没有理由仅根据大小对其进行分区。

于 2009-05-06T00:50:03.383 回答
3

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

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

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

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

在阅读了后面的回复之后,我觉得这更像是一个报告解决方案,应该批量处理或实时计算并存储在不属于事务系统的表中。将 180 万行带到计算移动平均线的中间层是无法扩展的。

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

于 2009-05-05T22:50:11.453 回答
2

fetchSize 属性按照postgres 手册中的描述工作。

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

感谢所有的反馈。

于 2009-05-07T04:12:05.433 回答
1

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

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

干杯。

于 2015-08-12T18:39:51.440 回答