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);
}
}
...全文
368 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毫秒?
内容概要:本文研究了计及碳排放的多微网电能交互分布式运行策略,提出了一种基于交替方向乘子法(ADMM)的优化方法,旨在实现多微电网系统在满足能源供需平衡的同时降低碳排放。文中构建了包含分布式电源、储能系统、可控负荷及碳排放约束的多微网协同优化模型,通过ADMM算法将全局优化问题分解为各微网子系统独立求解的子问题,实现分布式协同调度,在保障各微网自治性的同时兼顾系统整体的经济性与低碳性。研究通过Matlab代码完成了算法仿真,验证了所提策略在提升能源利用效率、减少碳排放、增强系统鲁棒性与可扩展性方面的有效性,为低碳化、去中心化的能源互联网运行提供了理论支持与实践参考。; 适合人群:具备电力系统分析、优化理论及Matlab编程基础的科研人员、电气工程及相关专业的研究生,以及从事智慧能源、分布式能源系统规划与运行的工程技术人员。; 使用场景及目标:①应用于多微电网系统的分布式能量管理与协同优化调度;②支持“双碳”目标下的低碳电网运行策略设计与政策评估;③为ADMM等分布式优化算法在能源系统中的工程化应用提供完整的模型构建、算法实现与仿真验证案例。; 阅读建议:读者应结合Matlab代码深入理解ADMM算法的迭代流程、拉格朗日函数构造与收敛条件设定,重点关注模型中碳排放因子的引入方式、变量分解机制与子问题求解过程,建议通过调整微网数量、碳价参数及通信拓扑结构进行多场景仿真,以深化对分布式协同机制与环保经济权衡关系的理解。
下载代码方式:https://pan.quark.cn/s/cc130f55eddd BUCK变换器,亦称为降压型转换器,在开关电源技术中属于一种基础电路拓扑,其核心功能在于实现从高电压到低电压的转换,并且在转换过程中确保输出端电压的稳定性。本文的核心内容集中在对BUCK变换器的运行机制进行剖析、阐释电流连续模式(CCM)与断续模式(DCM)之间的差异,并深入探讨这两种模式在稳态下的相互关系,同时研究BUCK变换器的交流等效电路模型以及电压与电流补偿回路的构建方法。BUCK变换器的原理示意图如图1所示,其显著特征在于输出电压值低于输入电压值,输出电流保持连续状态,而输入电流则呈现出脉动特性。变换器的工作过程可以划分为两个主要阶段:在第一个阶段,即开关管导通期间,电感元件负责储存能量,电流呈现出线性增长的趋势,并且同时向负载提供能量;在第二个阶段,即开关管截止期间,电感通过二极管实现能量的续流,电流则表现出线性递减的态势。依据电感元件的伏秒平衡原理,可以推导出涉及开关管占空比、电感元件电感量、输入电压以及输出电压之间关系的数学公式,这些公式对于深入理解和设计BUCK变换器具有关键性的指导意义。 接下来,文章对CCM和DCM两种模式进行了详细的比较分析。在CCM模式下,电感电流在整个开关周期内均保持连续的状态,而在DCM模式下,电感电流则会出现中断现象。确定BUCK变换器工作模式的关键依据是其电感电流纹波值与输出电流值相等这一边界条件。当电流纹波值等于零,即在整个开关周期内电感电流保持完全连续时,BUCK变换器被归类为CCM模式;相对地,若电流纹波值大于零,则表明变换器处于DCM模式;介于两者之间的情况则界定为CCM与DCM的过渡状态。 在DCM模式下,对BUCK...

62,621

社区成员

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

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