目前正在部署基于OFBiz的ERP,我们遇到了以下问题:框架的一些代码调用resultSet.last()来了解结果集的总行数。使用Oracle JDBC驱动程序v11和v10,它会尝试缓存客户端内存中的所有行,从而导致JVM崩溃,因为它没有足够的堆空间。
经过研究,问题似乎是Oracle JDBC通过使用缓存在客户端而不是在服务器中实现Scrollable Cursor。使用datadirect驱动程序,该问题已解决,但似乎对resultset.last()的调用需要太多才能完成,因此应用程序服务器会中止事务
有没有办法在oracle中通过jdbc实现可滚动游标而不需要使用datadirect驱动程序?
知道给定resultSet长度的最快方法是什么?
提前致谢 伊斯梅尔
答案 0 :(得分:1)
“知道给定resultSet长度的最快方法是什么” 真正了解的唯一方法是统计它们。你想知道电话簿中有多少'SMITH'。你算一算吧。 如果它是一个小的结果集,并迅速到达,这不是一个问题。 EG电话簿中不会有很多Gandalf,你可能想要把它们全部搞定。
如果它是一个大的结果集,你可能可以做一个估计,虽然这通常不是SQL设计得很好的。
为避免在客户端缓存整个结果集,您可以尝试
select id, count(1) over () n from junk;
然后每行将有一个额外的列(在本例中为n),其中包含结果集中的行数。但它仍然需要相同的时间才能达到计数,所以仍有很大的机会暂停。
妥协是获得前100行(或数千行),并且不要担心除此之外的分页。
答案 1 :(得分:0)
您建议的“解决方法”计数基本上会使DB服务器完成的工作增加一倍。它必须首先遍历所有内容以计算结果数量,然后执行相同的+返回结果。更好的是Gary提到的方法(count(*)over() - analytics)。但即使在这里,也必须在将第一个输出返回给客户端之前创建整个结果集。因此,对于大输出来说,内存消耗可能会很慢。
在我看来,最好的选择是在屏幕上仅选择您想要的页面(+1以确定下一个存在的页面),例如从21到41的行。并且有另一个按钮(用例)在有人需要它的(罕见)情况下对它们进行计数。