gpt4 book ai didi

java - CallableStatement 的性能下降

转载 作者:搜寻专家 更新时间:2023-11-01 00:56:53 25 4
gpt4 key购买 nike

我在 Oracle 11g 中有一个存储过程,我使用 Oracle 瘦数据库驱动程序和 CallableStatement 从 Java 程序调用它。此存储过程在同一连接上的循环中被调用数千次。

对于前 10-20 次调用,callableStatement.execute() 调用在 < 200 毫秒内返回,但是,性能会随着时间的推移而开始下降。调用 200 次后,callableStatement.execute() 现在需要 600 毫秒,并且还在继续下降。

如果我定期关闭连接,执行时间会恢复到正常的 < 200 毫秒范围内。很明显,JDBC 连接中缓存的内容不正确,尽管文档指出未缓存 CallableStatements。

在 C 程序中使用 Oracle OCI 驱动程序运行相同的存储过程显示没有性能下降,并且在 < 200 毫秒内连续返回。

有没有人注意到这种行为或对 Java 的解决方法有任何想法?

编辑:这是多次运行的代码部分;连接是共享的,每次循环都会创建 CallableStatement。如果 CallableStatement 被缓存,则没有改善。

   oracle_conn_time = System.currentTimeMillis();
OracleConnection oracle_conn = (OracleConnection) conn.getMetaData().getConnection();
oracle_conn.setStatementCacheSize(1);
oracle_conn_time = System.currentTimeMillis() - oracle_conn_time;

list_time = System.currentTimeMillis();
var_args= oracle_conn.createARRAY("ARG_LIST", args.toArray());
list_time = System.currentTimeMillis() - list_time;

sql = "{? = call perform_work(?,?,?,?)}";

prepare_time = System.currentTimeMillis();
ocs = (OracleCallableStatement) oracle_conn.prepareCall(sql);
prepare_time = System.currentTimeMillis() - prepare_time;

bind_time = System.currentTimeMillis();
ocs.registerOutParameter(1, OracleTypes.ARRAY, "RESPONSEOBJ");

ocs.setInt( 2, 77);
ocs.setInt( 3, 123456);
ocs.setArray(4, var_args);
ocs.setInt( 5, 123456789);
bind_time = System.currentTimeMillis() - bind_time;

//execute_time is the only timer that shows degradation
execute_time = System.currentTimeMillis();
ocs.execute();
execute_time = System.currentTimeMillis() - execute_time;

results_time = System.currentTimeMillis();
Array return_objs = ocs.getArray(1);
results_time = System.currentTimeMillis() - results_time;

oracle_time = System.currentTimeMillis() - oracle_time;
parse_time = System.currentTimeMillis();

Clob[] clobs = (Clob[]) return_objs.getArray();

return_objs.free();

//Removed clob management code

parse_time = System.currentTimeMillis() - parse_time;

最佳答案

当存储过程返回一个 Clob 数组时,代码只是直接释放数组,而不是底层的 Clob 对象。

在 Clob 对象上添加对 free 的调用消除了性能下降。

我假设当 Clob 对象被垃圾回收时,free 本质上在 finalize 中被调用,但我怀疑 Oracle Connection 对象持有对任何 Clob 对象的引用使用,从而防止它被垃圾收集。对我来说是愚蠢的错过,但希望这能帮助将来有人被绊倒。

Array return_objs = ocs.getArray(1);

Clob[] clobs = (Clob[]) return_objs.getArray();

return_objs.free();

for(int i = 0; i < clobs.length; i++ )
{
//Utilize clob

clobs[i].free();
}

关于java - CallableStatement 的性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20433977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com