java传递结构体数组给oracle存储过程,性能太差了

ATCG 2012-06-15 11:04:31
如下程序,调用一次存储过程要 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);
}
}
...全文
303 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2012-06-21
  • 打赏
  • 举报
回复
哦 很看好生物科学,大有可为。
ATCG 2012-06-18
  • 打赏
  • 举报
回复
曾经做过bioinformatics行业,现在改行了
[Quote=引用 18 楼 的回复:]
楼主研究生物的?ATCG...
[/Quote]
dracularking 2012-06-18
  • 打赏
  • 举报
回复
楼主研究生物的?ATCG...
ATCG 2012-06-15
  • 打赏
  • 举报
回复
谢谢,那咋办呢?
[Quote=引用 2 楼 的回复:]
存储过程很快,不用怀疑,单单 cstmt.execute(); 执行少于1豪秒
现在currentTimeMillis()显示要200豪秒

我循环100次,要16秒,因此和currentTimeMillis()没啥关系了


引用 1 楼 的回复:
先定位问题主要是哪边。

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



话说。。。你知道 0.5 毫秒是啥概念……
[/Quote]
dracularking 2012-06-15
  • 打赏
  • 举报
回复
新建这些对象,消耗是挺“大”的
ATCG 2012-06-15
  • 打赏
  • 举报
回复
存储过程很快,不用怀疑,单单 cstmt.execute(); 执行少于1豪秒
现在currentTimeMillis()显示要200豪秒

我循环100次,要16秒,因此和currentTimeMillis()没啥关系了

[Quote=引用 1 楼 的回复:]
先定位问题主要是哪边。

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



话说。。。你知道 0.5 毫秒是啥概念不?currentTimeMillis()能统计出0.5毫秒差距不?
[/Quote]
MiceRice 2012-06-15
  • 打赏
  • 举报
回复
先定位问题主要是哪边。

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



话说。。。你知道 0.5 毫秒是啥概念不?currentTimeMillis()能统计出0.5毫秒差距不?
ATCG 2012-06-15
  • 打赏
  • 举报
回复
我现在也考虑写临时表,但是每天写的量很大,日志也很大
写临时表0.5豪秒也是不够的

[Quote=引用 15 楼 的回复:]
因为你的问题是创建对象消耗,时间长;话说从你4000字符都不够来看,你原始数据量就不小。
而字符串的消耗时间是相对稳定的,所以才提出创建字符串。


另一种毛招是直接把数据写入临时表,然后存储过程从临时表中处理。用batchExecute的话,写数据的性能倒是非常高。

总的来说,要达到0.5毫秒搞定,恐怕远没有这么乐观。
[/Quote]
MiceRice 2012-06-15
  • 打赏
  • 举报
回复
因为你的问题是创建对象消耗,时间长;话说从你4000字符都不够来看,你原始数据量就不小。
而字符串的消耗时间是相对稳定的,所以才提出创建字符串。


另一种毛招是直接把数据写入临时表,然后存储过程从临时表中处理。用batchExecute的话,写数据的性能倒是非常高。

总的来说,要达到0.5毫秒搞定,恐怕远没有这么乐观。
ATCG 2012-06-15
  • 打赏
  • 举报
回复
这每一步耗时我都测试过了,最后一步 EXECUTe就要 1豪秒

传字符串很快么?对于ORACLE来说,能够接收的最多4000字节。这个是不够用的

[Quote=引用 13 楼 的回复:]
引用 12 楼 的回复:
OCI 和THIN 都测试过了,一样,照理OCI应该更快


从目前主流的测试情况来看,基本都是Thin更快。Anyway,如果你已经测试过,那就没啥好细化的了。

无非是看能否进一步挖掘,这400毫秒究竟主要是消耗在这几句话中哪些了。


如果最终啥招都不行了,就最后一招:直接传一个大字符串进去(类似JSON或更简单的固定分割符方式),存储过程自行拆解……
[/Quote]
MiceRice 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
OCI 和THIN 都测试过了,一样,照理OCI应该更快
[/Quote]

从目前主流的测试情况来看,基本都是Thin更快。Anyway,如果你已经测试过,那就没啥好细化的了。

无非是看能否进一步挖掘,这400毫秒究竟主要是消耗在这几句话中哪些了。


如果最终啥招都不行了,就最后一招:直接传一个大字符串进去(类似JSON或更简单的固定分割符方式),存储过程自行拆解该字符串。
ATCG 2012-06-15
  • 打赏
  • 举报
回复
OCI 和THIN 都测试过了,一样,照理OCI应该更快

[Quote=引用 11 楼 的回复:]
听起来有点匪夷所思。。。

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

另一种考虑是将OCI驱动换位Thin驱动,后者是纯Java驱动,这样可以大量减少JNI的转换开销。
[/Quote]
MiceRice 2012-06-15
  • 打赏
  • 举报
回复
听起来有点匪夷所思。。。

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

另一种考虑是将OCI驱动换位Thin驱动,后者是纯Java驱动,这样可以大量减少JNI的转换开销。
ATCG 2012-06-15
  • 打赏
  • 举报
回复
不好意思
仅执行 cstmt.execute() 耗费1豪秒
前面的话了400豪秒

[Quote=引用 8 楼 的回复:]
我晕,两个选项让你选其中一个,你就一句:“是啊”。。。。。。
[/Quote]
小坏猫 2012-06-15
  • 打赏
  • 举报
回复
毫秒?豪秒?
MiceRice 2012-06-15
  • 打赏
  • 举报
回复
我晕,两个选项让你选其中一个,你就一句:“是啊”。。。。。。
ATCG 2012-06-15
  • 打赏
  • 举报
回复
是啊
[Quote=引用 6 楼 的回复:]
发现所发帖子失败了。

请问下“单单 cstmt.execute(); 执行少于1豪秒”这句话是什么意思?
◎ 不设置数据,直接执行cstmt.execute()?那么存储过程也没啥好干的,必然很快。
◎ 设置了数据,但计时只计算cstmt.execute(); ?那么意味着前面 StructDescriptor、STRUCT、ARRAY 等这几句话就消耗了400毫秒?
[/Quote]
MiceRice 2012-06-15
  • 打赏
  • 举报
回复
发现所发帖子失败了。

请问下“单单 cstmt.execute(); 执行少于1豪秒”这句话是什么意思?
◎ 不设置数据,直接执行cstmt.execute()?那么存储过程也没啥好干的,必然很快。
◎ 设置了数据,但计时只计算cstmt.execute(); ?那么意味着前面 StructDescriptor、STRUCT、ARRAY 等这几句话就消耗了400毫秒?

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧