PreparedStatement,CallableStatement和性能注意事项

时间:2012-01-05 18:42:43

标签: java oracle stored-procedures jdbc

我需要从我的Java程序中调用oracle stored proc。我曾使用CallableStatement将参数传递给存储过程。我正在使用oracle瘦驱动程序(在Web逻辑服务器中配置相对于相关的jndi条目)。此存储过程没有任何OUT值。此存储过程接受一个数值,并根据收到的值在数据库中执行大量更新。

我得到一个连接对象,然后在循环中调用这个存储过程(20次传递20个数字)。当我从oracle客户端直接调用此存储过程时,执行将在2-3秒内完成。但是我的java代码无法预测这种行为。有些呼叫甚至需要30-40秒才能完成。

我尝试使用PreparedStatement代替CallableStatement,并且可以看到边际性能提升(尽管行为仍然不一致)。

  1. 考虑到storedproc没有任何OUT参数,在我的情况下使用PreparedStatement而不是CallableStatement是否可以?
  2. PreparedStatement有什么理由可以使CallableStatement的性能提升超过{{1}},还是我可能观察到的错误?
  3. 有没有更好的方法来解决这个性能问题?

2 个答案:

答案 0 :(得分:8)

从你的评论中,你已经在你的循环中准备好了。预处理语句(和可调用语句)的一个优点是,您可以准备一次,然后交换参数中传递的值;每次准备调用时都会有开销,所以如果你可以把它带到循环之外,你可能会发现运行时间减少了。您可能会发现关闭AutoCommit也会有所帮助,因为每次提交都会产生开销。

conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
    stmt.setInt(1, value);
    stmt.execute();
}
conn.commit();
conn.setAutoCommit(true);

conn.setAutoCommit(true)确实提交,但我发现明确更明确。)

答案 1 :(得分:2)

你不应该考虑使用批次吗?

conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
    stmt.setInt(1, value);
    stmt.addBatch();
}
stmt.executeBatch()
conn.commit();