PreparedStatement 、 CallableStatement 和性能注意事项
Posted
技术标签:
【中文标题】PreparedStatement 、 CallableStatement 和性能注意事项【英文标题】:PreparedStatement , CallableStatement and Performance Considerations 【发布时间】:2012-02-03 14:21:27 【问题描述】:我有一个 oracle stored proc
需要从我的 Java 程序中调用。我曾使用CallableStatement
将参数传递给存储过程。我正在使用 oracle 瘦驱动程序(在 Web 逻辑服务器中针对相关的 jndi 条目进行配置)。这个存储的过程没有任何 OUT 值。这个存储过程接受一个数值,并根据接收到的值在数据库中进行大量更新。
我得到一个连接对象,然后在循环中调用这个存储过程(传递 20 个数字 20 次)。当我直接从 oracle 客户端调用此存储过程时,执行将在 2-3 秒内完成。但是,从我的 java 代码中无法预测该行为。有些电话甚至需要 30-40 秒才能完成。
我尝试使用 PreparedStatement
而不是 CallableStatement
并且可以看到边际性能提升(尽管行为仍然不一致)。
-
鉴于 storedproc 没有任何 OUT 参数,就我而言是否可以使用
PreparedStatement
而不是 CallableStatement
?
PreparedStatement
比 CallableStatement
有一些性能提升,或者我可能没有正确观察到,有什么原因吗?
是否有更好的方法来解决此性能问题?
【问题讨论】:
你能贴出代码吗?或者,确认您的连接没有在每次迭代中建立(而不是重复使用一个连接),并确认您没有在每次迭代中调用conn.prepareCall()
(而不是只有.setInt()
和.execute()
在循环)。
您不止一次调用您的存储过程,对吗?您是否尝试过使用批量调用? docs.oracle.com/javase/1.3/docs/guide/jdbc/getstart/… 见 7.1.3
与其进行 20 次调用,不如尝试一个匿名的 PL/SQL 块(开始...调用 proc...调用 proc...end;)来调用您的存储过程 20次并使用匿名块对数据库进行一次调用。
我不允许在程序的 PL/SQL 部分上工作 :-( 正在进行单独的讨论以允许存储的 proc 将数字列表作为输入。对不起,如果我错误地理解了您的建议。
可以在 Java 端创建匿名 PL/SQL 块:CallableStatement cs = conn.prepareCall ("begin foo(?); end;");
【参考方案1】:
你不应该考虑使用批处理吗?
conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true)
stmt.setInt(1, value);
stmt.addBatch();
stmt.executeBatch()
conn.commit();
【讨论】:
【参考方案2】:根据您的评论,您的循环中有 prepareCall。准备好的语句(和可调用的语句)的一个优点是您可以准备一次,然后换出参数中传递的值;每次准备调用时都会产生开销,因此如果您可以将其带到循环之外,您可能会发现运行时间减少了。您可能会发现关闭 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)
确实提交了,但我发现更明确)。
【讨论】:
谢谢马特。我明白了很多,我相信这会解决我的问题。我会试试这个和塞尔吉奥的建议。感谢您的时间和帮助:) 嗨,马特 - 尝试了您和 Sergio 建议的两种方法,但通过我的 java 代码执行时仍然很慢。 更新:我想程序本身现在很慢,当我尝试使用我的 oracle 客户端直接访问该程序时 - 每个数字大约需要 2 分钟。这在一天中的不同时间表现不同,这是我需要调查的事情。感谢您的所有帮助。 那为什么不做一个存储过程批量插入呢?以上是关于PreparedStatement 、 CallableStatement 和性能注意事项的主要内容,如果未能解决你的问题,请参考以下文章
Statement与PreparedStatement的区别