2009-05-05 94 views
3

我正在对postgresql数据库中的表运行查询。数据库位于远程机器上。该表有大约30个使用postgresql partitioning capability的子表。postgresql查询上的大型结果集

该查询将返回一个大型的结果集,大约有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企业64位
  • JRE 1.6 64位
  • 春2.5.6
  • PostgreSQL JDBC驱动8.3-603
+0

您的电话正在返回吗?如果没有,你尝试了ctrl- \(Windows的ctrl-break),jstack,jconsole,visualvm或类似的找到线程停止的地方? – 2009-05-05 22:08:40

+0

它正在处理驱动程序内部的查询。 – tuler 2009-05-06 00:25:30

+0

另请参见https://stackoverflow.com/a/47517489/32453 – rogerdpack 2017-11-27 19:56:36

回答

4

为了使用游标检索数据,除了设置获取大小之外,还必须将ResultSet.TYPE_FORWARD_ONLY(缺省值)的ResultSet类型和autocommit设置为false。在您链接到的文档中引用了该内容,但您没有明确提及您执行了这些步骤。

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

2

我敢打赌,你的应用没有一个客户端这需要180万行同时。你应该想到一个合理的方法将结果分成较小的部分,并给用户遍历它们的机会。

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

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

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

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

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

2

fetchSize属性的工作方式如postgres manual所述。

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

感谢您的所有反馈。

0

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

我加了这一点:@Transactional(readOnly = true)

干杯。