3

在我的 java 代码中,我使用 select 语句访问一个 oracle 数据库表。我收到很多行(大约 50.000 行),因此rs.next()需要一些时间来处理所有行。

using ResultSet, the processing of all rows (rs.next) takes about 30 secs

我的目标是加快这个过程,所以我更改了代码,现在使用CachedRowSet

using CachedRowSet, the processing of all rows takes about 35 secs

我不明白为什么CachedRowSet比正常慢ResultSet,因为CachedRowSet一次检索所有数据,而ResultSet每次rs.next调用时检索数据。

这是代码的一部分:

try {
    stmt = masterCon.prepareStatement(sql);
    rs = stmt.executeQuery();

    CachedRowSet crset = new CachedRowSetImpl();
    crset.populate(rs);

    while (rs.next()) {
        int countStar = iterRs.getInt("COUNT");
        ...
    }
} finally {
    //cleanup
}
4

4 回答 4

4

CachedRowSet 将结果缓存在内存中,即您不再需要连接。因此,它首先“变慢”。

CachedRowSet 对象是数据行的容器,将其行缓存在内存中,这使得无需始终连接到其数据源即可进行操作。

-> http://download.oracle.com/javase/1,5.0/docs/api/javax/sql/rowset/CachedRowSet.html

于 2011-10-06T10:07:08.440 回答
4

CachedRowSet与 postgres jdbc 驱动程序耦合存在问题。

CachedRowSet需要知道列的类型,以便知道要创建哪些 java 对象(天知道它还从 DB 背后获取了什么!)。

因此,它对数据库进行了更多的往返以获取列元数据。在非常大量的情况下,这成为一个真正的问题。如果数据库位于远程服务器上,这也是一个真正的问题,因为网络延迟。

我们已经使用CachedRowSet了多年,才发现这一点。我们现在实现我们自己的CachedRowSet,因为无论如何我们从未使用过任何花哨的东西。我们getString为所有类型做并转换自己,因为这似乎是最快的方法。

这显然不是获取大小的问题,因为 postgres 驱动程序默认获取所有内容。

于 2012-08-03T18:08:51.470 回答
3

是什么让您认为ResultSet每次rs.next()调用都会检索数据?它的工作原理完全取决于实现——如果它一次获取一个块,我不会感到惊讶;很可能是相当大的一块。

我怀疑你基本上看到了将所有数据复制到然后CachedRowSet访问它所花费的时间——基本上你有一个额外的复制操作是没有目的的。

于 2011-10-06T10:08:42.597 回答
0

使用普通的 ResultSet,您可以通过 RowPrefetch 和 FetchSize 获得更多优化选项。

这些优化了网络传输块和 while 循环中的处理,因此 rs.next() 始终有一个数据可以使用。

FetchSize 的默认设置为 10(Oracle 最新版本),但据我所知,未设置 RowPrefetch。因此意味着网络传输根本没有优化。

于 2016-08-11T11:49:02.067 回答