日期:2014-05-20  浏览次数:20652 次

java传递结构体数组给oracle存储过程,性能太差了
如下程序,调用一次存储过程要 400豪秒,没法接受,可以接受的是 0.5豪秒以内,谢谢
import java.sql.*;
import java.util.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;

public class test
{
public static void main(String args[]) throws Exception
{

DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection con = DriverManager.getConnection("jdbc:oracle:oci8:@test","user","pass");
long time1 = System.currentTimeMillis() ;
OracleCallableStatement cstmt = (OracleCallableStatement) con.prepareCall("{call testInPersons(?)}");
  StructDescriptor sd = new StructDescriptor("PERSON", con);
  Object[] personAttrs1 = new Object[] { "This is code11", "100",new NUMBER(32), 200};
  STRUCT person1 = new STRUCT(sd, con, personAttrs1);
  Object[] personAttrs2 = new Object[] { "This is code22", "aaa", new NUMBER(33), 100 };
  STRUCT person2 = new STRUCT(sd, con, personAttrs2);
  ArrayDescriptor ad = new ArrayDescriptor("person_table_type".toUpperCase(), con);
  ARRAY persons = new ARRAY(ad, con, new STRUCT[] { person1, person2 });
  cstmt.setARRAY(1, persons);
  cstmt.execute();

long time2 = System.currentTimeMillis() ;
System.out.println(time2-time1);
}
}

------解决方案--------------------
先定位问题主要是哪边。

你直接在SQL工具中测试该存储过程,时间开销如何?



话说。。。你知道 0.5 毫秒是啥概念不?currentTimeMillis()能统计出0.5毫秒差距不?
------解决方案--------------------
新建这些对象,消耗是挺“大”的
------解决方案--------------------
发现所发帖子失败了。

请问下“单单 cstmt.execute(); 执行少于1豪秒”这句话是什么意思?
◎ 不设置数据,直接执行cstmt.execute()?那么存储过程也没啥好干的,必然很快。
◎ 设置了数据,但计时只计算cstmt.execute(); ?那么意味着前面 StructDescriptor、STRUCT、ARRAY 等这几句话就消耗了400毫秒?
------解决方案--------------------
我晕,两个选项让你选其中一个,你就一句:“是啊”。。。。。。
------解决方案--------------------
听起来有点匪夷所思。。。

不知道究竟是哪个对象的创建会这么慢,神奇。

另一种考虑是将OCI驱动换位Thin驱动,后者是纯Java驱动,这样可以大量减少JNI的转换开销。
------解决方案--------------------
探讨
OCI 和THIN 都测试过了,一样,照理OCI应该更快

我的异常网推荐解决方案:oracle存储过程,http://www.myexception.cn/oracle-develop/177537.html