java结果集。next()对于oracle ref游标来说太慢
我从java调用一个oracle过程,它返回一个ref游标作为结果。我将ref光标投射到一个ResultSet,然后迭代从它开始
String query = "{call ...(...)}";
CallableStatement stmt = conn.prepareCall(query,ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(10000);
.
.
.
stmt.registerOutParameter(x, OracleTypes.CURSOR);
stmt.execute();
Resultset rs = (ResultSet) stmt.getObject(x);
while (rs.next()) { /** Problem occurs here **/
...
}
问题是,有时(并非总是)对于某些特定记录,结果集。next()方法花费的时间太长(比如100秒)。需要指出的是,返回的记录最多为25条,并且数据库中的同一查询正常执行(执行时间约为6秒)
随着我的进一步调查,我发现在返回的游标中有一列,如果删除它,这个问题就不会发生。该列实际上是结果游标中包含的ROWNUM()
--ORACLE Query snippet:
OPEN result_cursor FOR
SELECT "FirstName","LastName", r
FROM (SELECT ROWNUM r, *
... -- query details
WHERE ROWNUM <= 25)
我甚至没有触及结果集中的那个字段,但它仍然会导致这个问题(这似乎不公平:())。我尝试在Oracle过程中将其转换为字符串(通过将其与“”连接),假设类型转换可能会导致此问题,但在这种情况下没有任何区别。 为什么会这样
# 1 楼答案
您所说的字段ROWNUM()是一个可变的值,因为可能会插入行,这实际上可能会改变绝对行数——在执行提取操作时,需要重新计算绝对行数,以说明自上次提取调用以来光标返回的表中的任何插入或删除。每次调用rs.next()都会导致一个fetch操作,因为该列是一个可变的值,即使您很快就能得到其余的结果
之所以会出现这种情况,是因为在导航结果集时,使用ref光标会使SELECT保持打开状态