CachedRowSet比ResultSet慢?

在我的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 } 

是什么让你认为每次调用rs.next()ResultSet都会检索数据? 这取决于它的实现方式 – 如果它一次取出一块,我也不会感到惊讶; 很可能是一个相当大的块。

我怀疑你基本上看到将所有数据复制到CachedRowSet 然后全部访问所需的时间 – 基本上你没有任何目的进行额外的复制操作。

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

CachedRowSet对象是用于将其行缓存在内存中的数据行的容器,这使得可以在不始终连接到其数据源的情况下进行操作。

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

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

CachedRowSet需要知道列的类型,因此它知道要创建哪些java对象(上帝知道它从封面后面的DB中获取了什么!)。

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

我们多年来一直在使用CachedRowSet ,并且发现了这一点。 我们现在实现了我们自己的CachedRowSet ,因为我们从来没有使用它的任何花哨的东西。 我们为所有类型做getString并转换自己,因为这似乎是最快的方式。

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

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

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

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