我使用带有存储过程的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();
}
除了获取大小以外,还有其他方法可以优化它吗?
我试过这个:
while(rs.next()) {`
logger(); // do nothing
}
它在大约3秒内处理了12000行,因此从resultSet中获取数据的时间已经消耗殆尽。
此外,确认setfetchSize()正常工作,因为没有设置提取大小它显示" fetchedRowCount"如果为10,并且setFetchSize()为x,则显示" 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秒。必须有一个解决方案。
提前致谢
答案 0 :(得分:0)
关于fetchSize的一点澄清。在你的代码中有一个带有out参数和CURSOR的CallableStatement。 SetFetchSize对CallableStatement没有影响,因为它只返回一组结果out参数。在这种情况下,只有一个输出参数CURSOR。 getCursor调用返回ResultSet。
最好我可以回想一下,JDBC规范中没有任何内容说明从CURSOR创建的ResultSet的fetchSize应该是什么。 (我的内存是错误的。)Oracle数据库JDBC驱动程序将CURSOR ResultSet的fetchSize设置为与创建它的Statement相同。
因此,在这种情况下,设置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秒?不是获取它们,而是处理它们。这是列的数量和类型以及如何处理它们的函数。您没有提供任何相关信息。