java - JDBC ResultSet 方法 next() 需要 30 秒才能获取 12000 行

标签 java oracle jdbc

我正在使用 CallableStatement 和存储过程来获取数据,ResultSet 有 12000 行,处理需要 30 秒。我尝试设置获取大小(rs.setFetchSize(500),但仍然需要相同的时间来获取整个数据(30 秒)。

callableStatement = conn.prepareCall(myProc);
callableStatement.setString("myParam", xyz);
callableStatement.registeroutputParameter("REVTAL", OracleTypes.CURSOR);
callableStatement .setFetchSize(1000); // I have tried with different values
rs = (ResultSet) callableStatement.getObject("REVTAL");

while(rs.next()) {`
    myMethodToSetResultIntoList();
}

除了获取 Size 之外还有其他可能的方法来优化它吗?

我已经尝试过这个:

while(rs.next()) {`
        logger(); // do nothing
    }

它在大约 3 秒内处理了 12000 行,因此从 resultSet 中获取数据会消耗时间。

此外,已确认 setfetchSize() 工作正常,因为在没有设置 fetch Size 的情况下,它显示“fetchedRowCount”为 10,而 setFetchSize() 为 x,则在 Debug模式下将“fetchRowCount”显示为 x。

实际的while循环是这样的:

while(rs.next()) {
    Myclass mc = new Myclass();
    mc.setA(rs.getString("parameterA");
    mc.setB(String.valueOf(rs.getLong("parameterB");
    //4 more string parameters same
    mc.setG(myMethodToConvertDate(rs.getDate("Date");
    myList.add(mc);
}

因此,从 resultSet 检索数据并将其添加到 myList 大约需要 25 秒。必须有一个解决方案。

提前致谢

最佳答案

关于 fetchSize 的一些说明。在您的代码中有一个带有输出参数和游标的 CallableStatement。 SetFetchSize 对 CallableStatement 没有影响,因为它只返回一组结果,即输出参数。在这种情况下,只有一个输出参数,即 CURSOR。 getCursor 调用返回一个 ResultSet。

我记得 JDBC 规范中没有任何内容说明从 CURSOR 创建的 ResultSet 的 fetchSize 应该是多少。 (我的内存有误。)Oracle 数据库 JDBC 驱动程序将 CURSOR 结果集的 fetchSize 设置为与创建它的语句相同。

因此,在这种情况下,设置 CallableStatement 的 fetchSize 对 CallableStatement 检索的结果没有任何作用,但它确实设置了从 CURSOR 创建的 ResultSet 的 fetchSize。因此,Usagi Miyamoto 的评论至少在 CallableStatement 方面是正确的,但您关于通过设置 fetchSize 看到预期行为的评论也是正确的。

迭代 CURSOR ResultSet 会从数据库中获取所有数据。你说这大约需要 3 秒。处理行时大约需要 20 秒。设置 fetchSize 不会加快(或减慢)行处理速度,只会加快数据库提取速度。因此,在限制范围内设置 fetchSize 不会加快速度。 (这些限制是 fetchSize 必须足够大,以最大限度地减少数据库往返次数,并且足够小,以保持内存占用合理。100 通常是一个不错的数字。很少有任何更大的值会明显更好。)

但是当 fetchSize 为 1000 时,您的代码将在 3 秒内获取所有行。 100 可能会让您的应用程序整体运行得更快,因为它使用的内存更少,但这对您的问题来说是次要的。您真正的问题是为什么处理 12,000 行需要大约 17 秒?不是获取它们,而是处理它们。这是列的数量和类型以及它们的处理方式的函数。您尚未提供这方面的任何信息。

关于java - JDBC ResultSet 方法 next() 需要 30 秒才能获取 12000 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45758404/

相关文章:

java - 提交页面并没有更新我的模型?

java - 如何在 `main()` 中创建 Iterator 私有(private)类的实例

sql - Oracle:如何设置用户密码未过期?

mysql - 使用 UNION 从结果集中的各个表中获取列值

java - JPEG 原始 blob 中的 "metadata"边界到底在哪里?

oracle - 在没有业务限制的情况下,我应该为 Oracle 字符类型设置什么限制?

.net - 使用 YES/NO 值将复选框绑定(bind)到数据表

java - 如何将 MS JDBC 驱动程序与 MS SQL Server 2008 Express 一起使用?

mysql - Kafka Connect JDBC 连接器查询 + 在初始轮询时使用大数据集增加模式阻塞

java - 尝试从字符串中提取某些数字