|
原帖由 newkid 于 2009-2-20 02:32 发表 ![]()
我对那些饱受煎熬的C程序员的建议是:
把你们的聪明才智和宝贵时间用来学习SQL和PLSQL编程;把原来的程序尽量移植到存储过程中,C代码越少越好。
如果寄希望于某个包装器能够摆脱SQL,那么你就写不出高效访问数据库的代码,永远掌握不了数据库应用的精髓。
对于这个UPDATE提速的现象,我一直怀疑你没有执行到INSERT出错的部分,因为一旦出错时间就会倍增。
为了证明这一点,我们可以加一个简单的计数器。
环境设置:
CREATE TABLE tjrb_test_log (cnt NUMBER);
INSERT INTO tjrb_test_log VALUES (0);
COMMIT;
CREATE OR REPLACE TRIGGER tjrb_ins BEFORE INSERT ON tjrb FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE tjrb_test_log SET cnt = cnt+1;
COMMIT;
END;
/
这样每次INSERT, 不管成功与否,计数器都会递增。多了这个触发器当然会使得你的UPDATE和INSERT比原来略慢,但是有助于我们发现问题。
当你每次开始一轮新的实验之前,先把计数器清空:
UPDATE tjrb_test_log SET cnt=0;
COMMIT;
现在需要你做的实验时:
先让表中装载数据(为了让第二次出错);
清空计数器;
执行你的“提速”代码;
SELECT * FROM tjrb_test_log;
这样可以清楚地看到,在你的提速UPDATE之前是不是真的发生了7552次INSERT?
我对那些饱受煎熬的C程序员的建议是:
把你们的聪明才智和宝贵时间用来学习SQL和PLSQL编程;把原来的程序尽量移植到存储过程中,C代码越少越好。
如果寄希望于某个包装器能够摆脱SQL,那么你就写不出高效访问数据库的代码,永远掌握不了数据库应用的精髓。
业务逻辑一旦变更,一群程序员会发疯的。再说,我这个包装器效率很高啊,而且还能把负载分担到中间服务器。看我前边的时间统计,所有user、sys时间都是在应用服务器开销的,极大减轻数据库服务器的压力。
看现在这个程序,多舒服,就如Hibernate说的,“优雅的程序”,数据结构修改一点不用着急(修改好几次了),而且速度一点不慢。
/* 席位申请 接收格式:
reqst="上车日期|全车次|上车站略码|下车站顺号|席别|用途|数量|"
返回结果在result中,JSON对象。被送到客户端。
*/
int getxw(GDA *ctx,char *reqst,JSON_OBJECT result,char *msg)
{
int ret,i;
INT64 now;
SEAT_stu seat;
T_PkgType seat_sub_tpl[6];
struct mkseat_stu app;
DAU seat_DAU,seat_sub_DAU;
JSON_OBJECT json_array;
SRM app_SRM;
if(!msg||!result) return -1;
now=now_sec();
*msg=0;
SRM_init(&app_SRM,0,&app,mkseat_tpl);
SRM_dispack(&app_SRM,reqst); //拆包
DAU_init(&seat_DAU,ctx->SQL_Connect,0,&seat,SEAT_tpl);
//生成子模板,一共就涉及了这5个字段,只要不删除这5个,其他随便改,与本程序无关。
partt_copy(seat_sub_tpl,SEAT_tpl,"flag, used_dev, used_uid, used_time, ROWID");
DAU_init(&seat_sub_DAU,ctx->SQL_Connect,0,&seat,seat_sub_tpl);
ret=SRM_copy(&seat_DAU.srm,&app_SRM,0);//检索条件装入seat_DAU
if(0!=getSeat_for_sell(&seat_DAU,app.quantity,msg)) { // seat_DAO.c
DAU_free(&seat_DAU);
return -1;
}
json_array=json_object_new_array();
if(!json_array) {
DAU_free(&seat_DAU);
sprintf(msg,"getxw:Malloc json_array error");
return MEMERR;
}
for(i=0;i<app.quantity;i++) {
JSON_OBJECT json;
if(ret=GET_NEXT_DAO(&seat_DAU)) {
break;
}
seat.flag=1;
seat.used_time=now;
strcpy(seat.used_uid,ctx->contex.userid);
strcpy(seat.used_dev,ctx->contex.devid);
ret=updateSeat_by_ROWID(&seat_sub_DAU,msg);//seat_DAO.c
if(ret != 1) {
ShowLog(1,"占用席位失败,stmt=%s,ROWID=%s", msg,seat.ROWID);
i--;
continue;
}
seat.end_station = app.arrive;
/* 结果打JSON包 */
json = json_object_new_object();
if(!json) MERR_RET
DAU_toJSON(&seat_DAU,json,0);
json_object_array_add(json_array,json);
}
DAU_free(&seat_DAU);
if(i==0) {
ctx->SQL_Connect->Errno=SQLNOTFOUND;
return 0;
}
json_object_object_add(result,"seat_data",json_array);
return i;
}
我们已经辩论这么久了,为什么时至今日你还主观断言包装器一定低效呢?低效不低效,要看水平,所以我的题目叫“ 看我做的数据库包装器”如何。
这不完全是我的水平,你也有一份。就像自动档的车,老师傅看不起,其实做好了也费不了多少油,对于新手来说,并不比笨手笨脚的开手动档费。
这个程序,你也可以理解为C的存储过程,实际对客户端而言就是这么回事。这个程序没比谁慢哦!经初步测试,比IBM的TPF要快很多倍哦!
http://www-01.ibm.com/software/htp/tpf/
插入动作肯定是完成了,错误信息都出来了。唯一键约束违例,只不过我没打日志,故意不打的,太多。
loadasc:load 0 rec's time=6,buf=bind_ins:sqlo_execute=-1,errmsg=ORA-00001: unique constraint (TICKET.SYS_C0011534) violated,tabneme=tjrb,
bind=1:tjdate=2006.01.31,2:unit=55,3:tabname=A7,4:flg=102,5:dat1=0,6:dat2=0,7:dat3=0,8:dat4=0,9:dat5=0,10:dat6=0,11:dat7=0,
12:dat8=0,13:dat9=0,14:dat10=0,15:dat11=0,16:dat12=0,17:dat13=0,18:dat14=0,19:dat15=0,20:dat16=0,21:dat17=0,22:dat18=0,
23:dat19=0,24:dat20=0,25:dat21=0,26:dat22=0,27:dat23=0,28:dat24=0,29:dat25=0,30:dat26=0,31:dat27=0,32:dat28=0,33:dat29=0,
34:dat30=0,35:dat31=0,36:dat32=0,37:dat33=0,38:dat34=0,39:dat35=0,40:dat36=0,41:dat37=0,42:dat38=0,43:dat39=0,44:dat40=0,
45:dat41=0,46:dat42=0,47:dat43=0,48:dat44=0,49:dat45=0,50:dat46=0,51:dat47=0,52:dat48=0,53:dat49=0,54:dat50=0,
按你说的,把bind值打出来。这是最后一条记录。如果是第一条,有一个insert语句,后来的都没有了。
[ 本帖最后由 yulihua49 于 2009-2-20 17:11 编辑 ] |
|