我正在对使用JDBC的Oracle 10g(使用最新的驱动程序和UCP作为数据源)运行查询,以检索CLOB(平均20k个字符)。但是,性能似乎很差:100个LOB的批量检索平均需要4 s。从我的观察来看,该操作既不是I/O也不是CPU,也不是网络绑定(bind)的。
我的测试设置如下所示:
PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");
dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");
final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);
j.query("SELECT bigClob FROM ...",
new RowCallbackHandler() {
public void processRow(final ResultSet rs) throws SQLException {
String result = handler.getClobAsString(rs, "bigClob");
}
});
}
我尝试了提取大小,但无济于事。难道我做错了什么?使用JDBC时,有没有一种加快CLOB检索的方法?
最佳答案
我过去使用oracle LOB类型数据存储大数据的经验并不好。在4k以下时,这很好,因为它像varchar2一样在本地存储。一旦超过4k,您就会开始发现性能下降。也许,自从几年前我上一次尝试以来,情况可能有所改善,但是以下是我过去发现的情况,供您引用:
由于客户端需要通过oracle服务器获取LOB,因此您可以考虑以下有趣的情况。
如果是oracle,则使用其他数据类型进行缓存
决定缓存它。由于clob数据
一般大,所以可能会推其他
数据
oracle决定不缓存它,并且
将数据流传输到客户端。
您还没有遇到过。您将看到您的应用程序是否删除lob,并且oracle尝试重用该lob。我不知道oracle是否支持对lob的磁盘进行碎片整理(它们具有索引),但是我们上一次尝试时需要花费很长时间。
您提到100 lob的平均值为20k时为4s,因此每个lob为40ms。请记住,每个lob需要通过单独的Lob定位器进行检索(默认情况下不在结果集中)。我假设这是每个lob的额外往返行程(由于前一阵子,我对此并不十分确定)。如果是这种情况,我假设按顺序排列每次往返行程至少要多花5毫秒的时间, 正确的?如果是这样,则您的性能已经首先受到顺序lob提取的限制。您应该能够通过跟踪花费在sql执行和lob内容获取上的时间来验证这一点。或者,您可以通过排除帖子中上一个答案所建议的lob列来验证这一点,它应该告诉您它是否与lob相关。
祝你好运
关于performance - Oracle CLOB性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1525780/