2009-06-29 56 views
2

当前正在部署基于OFBiz的ERP,我们遇到了以下问题:框架的一些代码调用resultSet.last()来了解结果集的总行数。使用Oracle JDBC Driver v11和v10,它会尝试缓存客户机内存中的所有行,导致JVM崩溃,因为它没有足够的堆空间。Oracle是否通过JDBC支持服务器端可滚动游标?

经过研究,问题似乎是Oracle JDBC通过使用缓存在客户端而不是服务器中实现Scrollable Cursor。使用datadirect驱动程序,该问题已解决,但似乎对resultset.last()的调用需要太多才能完成,因此应用程序服务器会中止事务

是否有任何方法通过jdbc实现可滚动游标oracle而不诉诸于datadirect驱动程序?

什么是知道给定结果集长度的最快方法?

在此先感谢 伊斯梅尔

+0

我会先问一个切线问题;你同时需要结果集的数据和大小,还是只需要执行一个COUNT(*)类型的查询来查找行数?你是否真的需要行数呢?我曾多次看到过这样的情况:如果程序在真正不需要的时候花费很多时间获取分页行的总数,那么这种情况非常昂贵。 – Gandalf 2009-06-29 21:32:02

+0

需要确定分页方案中的页数。我们试图避免使用last,并使用iterator next()方法检查null来计算currentIndex。有没有一种快速的方法来知道没有使用last()方法的页数。 我们的解决方法是使用相同的条件执行COUNT查询,然后执行数据查询 – Ismael 2009-06-29 22:04:42

回答

1

“什么是知道一个给定的结果集的长度以最快的方式” 只有这样,才能真正知道是指望他们所有。你想知道电话簿中有多少个'SMITH'。你数它们。 如果它是一个小的结果集,并很快到达,这不是问题。 EG电话簿中不会有很多Gandalfs,你可能想要把它们全部拿回来。

如果它是一个较大的结果集,您可能可以进行估计,但这通常不是SQL精心设计的。

以避免缓存整个结果在客户端设置,你可以尝试

select id, count(1) over() n from junk; 

然后每一行都会有一个额外的列(在这种情况下,n)与行的结果集数。但它仍然需要花费相同的时间来计算,所以仍然有很大的超时时间。

妥协是得到第一百(或千)行,不要担心分页以外的分页。

0

您提议的“解决方法”与计数基本上使数据库服务器完成的工作翻倍。它必须首先遍历所有内容来计算结果数量,然后执行相同的+返回结果。 Gary提到的方法(count(*)over() - analytics)更好。但即使在这里,整个结果集也必须在第一个输出返回给客户端之前创建。所以它可能会减慢大容量输出的内存消耗。

我认为最好的办法是在屏幕上只选择你想要的页面(+1来确定下一个存在)例如从21到41行。并有另一个按钮(用例)来统计他们所需要的(罕见)情况。