关于CallableStatement执行效率问题

liguiqing 2006-04-29 11:00:19
在Oracle(9.0.1)先将要处理的数据(1000条以上)插入临时表,然后再调用一存储过程对这批数据进行集中处理,并返回处理信息,此存储过程在PL/SQL环境相同数据量下测试执行时间为10秒左右,但是通过CallableStatement去执行需要130秒左右(即调用executeQuery()后消耗的时间),经过测试,存储过程执行完成的时间也在10秒左右,但是在执行完返回的过程中消耗上百秒,如果去除返回值,也还需要50秒左右,百思不得其解,不知是否与驱动程序有关?(驱动为oracle的classes12.zip)
...全文
390 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jerry_Gao 2006-12-16
  • 打赏
  • 举报
回复
帮顶一下.我也面临同样的问题啊。
一个查询,用SQL PLUS执行大约1S(在清空过BUFFER CACHE 和 SHARED POOL的情况下).
用PreparedStatement执行就10S.
效率降低大约10倍.

希望高手来帮忙啊。
wd_6532 2006-11-18
  • 打赏
  • 举报
回复
mark
liguiqing 2006-04-30
  • 打赏
  • 举报
回复
游标的效率低?何解?为什么同样的数据量在PL/SQL下测试,执行效率就高了10多信
liguiqing 2006-04-30
  • 打赏
  • 举报
回复
完整的程序:
public List executeCallable(final String plsqlName, final Object[] params) {
return (List) new DataAccssesExecuteTemplet().run(new ITemplet() {
public Object execute() throws SQLException {
List results = null;
String plsql = getPLSQL(plsqlName, params);
LogHelper.logger.info("executeStatement: " + plsql);
Connection cn = null;
CallableStatement cs = null;
try {
cn = getConnection();
cs = cn.prepareCall(plsql);
setParamToStatement(cs, params,true);

cs.execute();//1000条数据,就这个调用需要130S,在PL/SQL下测试相同数据量,只要10S
results = parseStatement(cs, params);
} finally {
closeCallable(cs, cn);
}
return results;

}

private String getPLSQL(String plsqlName, Object[] params) {
StringBuffer parameters = new StringBuffer();
boolean hashReturnValue = true;
if((params[0]+"").startsWith("OracleTypes")){
parameters.append("{ ? = call " + plsqlName + "(");

}else{
parameters.append("{ call " + plsqlName + "(");
hashReturnValue = false;
}
for (int i = 0; i < params.length; i++) {
parameters.append("?,");
}
if(parameters.length()>3 && hashReturnValue)
parameters.delete(parameters.length()-3,parameters.length());
else
parameters.delete(parameters.length()-1,parameters.length());
parameters.append(") }");
return parameters.toString();
}

// 执行SQL语句并返回一个List封装的多个返回参数集
private List parseStatement(CallableStatement cs, Object[] params)throws SQLException {
ArrayList list = new ArrayList();
for (int i = 0; i < params.length; i++) {
String value = params[i] + "";
if (value.startsWith("OracleTypes")) {
if ("OracleTypes.CURSOR".equals(value)) {
ResultSet rs = (ResultSet) cs.getObject(i + 1);
list.add(covered(rs));
closeAll(rs, null, null);
} else {
list.add(cs.getObject(i + 1));
}
}
}
return list;
}
});
}
kingofworl 2006-04-30
  • 打赏
  • 举报
回复
应该是游标的效率低
liguiqing 2006-04-30
  • 打赏
  • 举报
回复
程序如下,请大家瞅瞅:
public Object execute() throws SQLException {
List results = null;
String plsql = getPLSQL(plsqlName, params);
LogHelper.logger.info("executeStatement: " + plsql);
Connection cn = null;
CallableStatement cs = null;
try {
cn = getConnection();
cs = cn.prepareCall(plsql);
setParamToStatement(cs, params,true);
 
cs.execute();//1000条数据,就这个调用需要130S,在PL/SQL下测试相同数据量,只要10S

results = parseStatement(cs, params);
} finally {
closeCallable(cs, cn);
}
return results;
jiaojian843 2006-04-30
  • 打赏
  • 举报
回复
应该不是与驱动程序有关,在看看其它的地方。
代码下载链接: https://pan.quark.cn/s/b27638adc362 在工业自动化监控领域中,WinCC 被视为一种常用的可视化软件,其功能在于构建人机界面(HMI)以及SCADA系统。本资料将阐释在WinCC环境下如何构建一个展现管道中流体流动的动态效果,此功能主要通过C动作脚本来完成。在此过程中,我们需要构建两个矩形,分别标记为 rec1 和 rec2。这两个矩形的高度相等,但 rec1 的宽度要小于 rec2。在具体实施时,rec1 将作为展示流体运动的可见单元,而 rec2 则作为辅助元素,尽管其“显示”属性被设为关闭,但在程序执行期间,其属性参数对流体动画的表现起着决定性作用,因为 rec2 与 rec1 的宽度差将决定流体每次移动的长度。 随后,我们需要将 rec1 和 rec2 整合为一个自定义对象。在自定义对象的属性配置中,应包含 rec1.Left、rec1.Width、rec1.Visible 和 rec2.Width 这些核心属性。这些属性将有助于在C脚本中精确控制对象的位置和可见状态,以达成流体运动的视觉效果。同时,用户可根据实际需求增加其他属性,以增强自定义对象的功能性。 在自定义对象的C脚本部分,我们设定了一个周期为“250ms”的触发器。该脚本的核心职责是计算并更新流体块的位置。借助 GetPropBOOL、GetPropWord 和 GetLeft 函数,我们可以获取对象的当前状态,涵盖其可见性、位置及宽度等参数。在循环操作中,流体块(rec1)将向右移动 rec2 - rec1 的距离,一旦流体块移出显示范围(即 rec1 的右边界达到或超过 rec2 的左边界),它将重新回到起始位置,从而形成流体持续流动的模...

62,622

社区成员

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

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