CallableStatement 的性能下降

Posted

技术标签:

【中文标题】CallableStatement 的性能下降【英文标题】:Performance Degradation on CallableStatement 【发布时间】:2013-12-24 09:34:51 【问题描述】:

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

对于前 10 到 20 次调用,callableStatement.execute() 调用在 callableStatement.execute() 现在需要 600 毫秒,并且会继续降级。

如果我定期关闭连接,执行时间会恢复到正常的

在 C 程序中使用 Oracle OCI 驱动程序运行相同的存储过程没有显示性能下降,并且在

有没有人注意到这种行为或对 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;

【问题讨论】:

你能发布你的代码吗?验证以下链接,在我看来类似的问题***.com/questions/8747937/… 如果每 10 次调用提交一次会发生什么? @MarkRotteveel 添加提交没有帮助。在上面添加代码 【参考方案1】:

当存储过程返回一个 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();

【讨论】:

以上是关于CallableStatement 的性能下降的主要内容,如果未能解决你的问题,请参考以下文章

施耐德st编程语言里上升沿和下降沿的符号是啥

台达plc编程问题 ST中如何使用上升沿触发

CPU用久了,性能不会下降吗?

CallableStatement 与语句

说说StatementPreparedStatement和CallableStatement的异同(转)

JDBC之Statement,PreparedStatement,CallableStatement的区别