2

目前正在部署基于 OFBiz 的 ERP,我们遇到了以下问题:框架的一些代码调用 resultSet.last() 来了解结果集的总行数。使用 Oracle JDBC Driver v11 和 v10,它尝试缓存客户端内存中的所有行,导致 JVM 崩溃,因为它没有足够的堆空间。

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

有什么方法可以在 oracle 中通过 jdbc 实现可滚动游标,而无需借助 datadirect 驱动程序?

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

提前感谢伊斯梅尔

4

2 回答 2

1

“知道给定结果集长度的最快方法是什么”真正知道的唯一方法是把它们都数一遍。您想知道电话簿中有多少个“史密斯”。你数一数。如果它是一个小的结果集,并且很快到达,那不是问题。EG 电话簿中不会有很多甘道夫,无论如何你可能都想得到它们。

如果它是一个大的结果集,您可能能够进行估计,尽管这通常不是 SQL 精心设计的目标。

为了避免在客户端缓存整个结果集,您可以尝试

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

然后每一行将有一个额外的列(在本例中为 n),其中包含结果集中的行数。但是到达计数仍然需要相同的时间,因此超时的可能性仍然很大。

折衷方案是获取前一百(或一千)行,并且不必担心除此之外的分页。

于 2009-06-30T01:40:27.670 回答
0

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

Best way in my opinion is select only the page you want on the screen (+1 to determine that next one exists) e.g. rows from 21 to 41. And have another button (usecase) to count them all in the (rare) case someone needs it.

于 2009-06-30T09:09:13.760 回答