gpt4 book ai didi

java - ResultSet.next() 对于 oracle ref cursor 来说太慢了

转载 作者:搜寻专家 更新时间:2023-11-01 03:37:20 25 4
gpt4 key购买 nike

我从 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 **/
...
}

问题是有时(并非总是)对于某些特定记录,ResultSet.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)

我什至没有触及 ResultSet 中的那个字段,但它仍然会导致这个问题(这似乎不公平 :( )。我试图在 Oracle 过程中将它转换为字符串(通过将它与 ' ' 连接),假设类型转换可能会导致此问题,但对情况没有影响。为什么会这样?

最佳答案

您正在谈论的字段 ROWNUM() 是一个可变值,因为可能会插入行,这实际上可能会更改绝对行号 - 然后需要在执行提取操作时重新计算,以说明任何从上次 fetch 调用后游标返回的表中插入或删除。每次调用 rs.next() 都会导致提取操作,因为该列是一个可变值,即使您很快就获得了其余结果。

发生这种情况是因为在您导航 ResultSet 时使用引用游标使选择保持打开状态。

关于java - ResultSet.next() 对于 oracle ref cursor 来说太慢了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27018186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com