Java 准备报表、可赎回报表和性能注意事项
我有一个需要从Java程序调用的Java 准备报表、可赎回报表和性能注意事项,java,oracle,stored-procedures,jdbc,Java,Oracle,Stored Procedures,Jdbc,我有一个需要从Java程序调用的oracle存储过程。我使用CallableStatement将参数传递给存储的进程。我正在使用oracle精简驱动程序(在web logic server中针对相关jndi条目进行配置)。此存储的进程没有任何OUT值。这个存储过程接受一个数值,并根据接收到的值在数据库中进行大量更新 我得到一个连接对象,然后在循环中调用这个存储的过程(传递20个数字需要20次)。当我从oracle客户机直接调用这个存储过程时,执行将在2-3秒内完成。但是,从我的java代码中无法
oracle存储过程
。我使用CallableStatement
将参数传递给存储的进程。我正在使用oracle精简驱动程序(在web logic server中针对相关jndi条目进行配置)。此存储的进程没有任何OUT值。这个存储过程接受一个数值,并根据接收到的值在数据库中进行大量更新
我得到一个连接对象,然后在循环中调用这个存储的过程(传递20个数字需要20次)。当我从oracle客户机直接调用这个存储过程时,执行将在2-3秒内完成。但是,从我的java代码中无法预测这种行为。有些通话甚至需要30-40秒才能完成
我尝试使用PreparedStatement
而不是CallableStatement
,可以看到性能的轻微改善(尽管行为仍然不一致)
PreparedStatement
而不是CallableStatement
可以吗PreparedStatement
比CallableStatement
在性能上有所提高,或者我可能没有正确地观察到这一点根据您的评论,您的循环中有prepareCall。prepared语句(和callable语句)的一个优点是,您可以准备一次,然后交换参数中传递的值;每次准备调用时都会有开销,因此如果您可以将其带到循环之外,您可能会发现运行时间会减少。您可能会发现关闭自动提交也会有所帮助,因为每次提交都会有开销
conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
stmt.setInt(1, value);
stmt.execute();
}
conn.commit();
conn.setAutoCommit(true);
(<代码> CON.SETAutoRebug(True)确实提交,但我发现它更明确).< /P>
不应该考虑使用批处理?< /P>
conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
stmt.setInt(1, value);
stmt.addBatch();
}
stmt.executeBatch()
conn.commit();
你能帮我寄密码吗?或者,确认没有在每次迭代中建立连接(而不是重复使用一个连接),并确认没有在每次迭代中调用
conn.prepareCall()
(而不是在循环中只调用.setInt()
和.execute()
).您多次调用存储过程,对吗?你试过使用批处理调用吗?请参阅7.1.3与其进行20次调用,为什么不尝试匿名PL/SQL块(begin…call proc…call proc…end;)调用存储的进程20次,并使用匿名块对数据库进行一次调用。我不允许处理程序的PL/SQL部分:-(有一个单独的讨论正在进行中,以允许存储过程将数字列表作为输入。如果我错误地理解了您的建议,很抱歉。您可以在Java端创建匿名PL/SQL块:CallableStatement cs=conn.prepareCall(“begin foo(?);end;”);谢谢Matt。我更了解这一点。我相信这会解决我的问题。我将尝试这一点和Sergio的建议。感谢您的时间和帮助:)嗨,Matt-尝试了您和Sergio建议的两种方法,但通过我的java代码执行时仍然很慢。更新:我想现在这个过程本身非常慢,当我尝试直接使用oracle客户端访问该过程时,每个数字大约需要2分钟。这在一天的不同时间和时间表现不同这是我需要调查的事情。谢谢你的帮助。那为什么不进行存储过程批插入呢?