准备语句 、可调用语句和性能注意事项

2022-09-04 22:00:13

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

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

我试图使用而不是,并且可以看到边际性能改进(尽管行为仍然不一致)。PreparedStatementCallableStatement

  1. 在我的情况下,是否可以使用而不是给定存储过程没有任何OUT参数?PreparedStatementCallableStatement
  2. 是否有任何原因导致性能有所提高,或者我可能观察到错误?PreparedStatementCallableStatement
  3. 有没有更好的方法来解决此性能问题?

答案 1

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

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

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


答案 2

难道不应该考虑使用批处理吗?

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

推荐