前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于评审开发人员的sql语句(r3笔记第11天)

关于评审开发人员的sql语句(r3笔记第11天)

作者头像
jeanron100
发布2018-03-14 17:41:27
6760
发布2018-03-14 17:41:27
举报

在平时的工作中,经常会有一些开发人员提出一些数据库相关的一些问题。可能问的最多的就是sql语句了。 按照一个标准的流程,开发提交的sql语句在完成一系列测试之后,在生产部署前,还需要dba来进行审核。如果是紧急的补丁,也一定不要漏了这个问题。 有时候是开发嫌麻烦,要不就是开发嫌dba麻烦,这个review的过程还是很必要的。 在之前的系统迁移中,印象比较深的一个例子就是,开发写了一个Pl/sql,在测试环境中因为没有大量的数据做测试,测试环境美发现任何问题,结果在生产环境部署的时候就直接提交给客户,dba没有做review,等我发现的时,已经是马上要开始系统升级的时候了。当时感觉不妥而且很郁闷,但是如果要调优,时间也来不及了。就硬着头皮开始系统升级。结果在其它部分进展都很顺利,就唯独这个Pl/sql有严重的问题,本来预计半个小时内就要跑完的程序,结果最后硬生生的跑了4个小时,眼看着rollback的时间越来越近了。在这个煎熬的过程中也在同时做性能调优,大半夜的在那调优,背后一大堆人看着,很不自在。 最后发现用几个简单的sql语句就完全可以替代pl/sql,在一个临时的表中进行了测试,结果不到1分钟就执行完了。 更多的调优细节,可以参考:生产系统pl/sql调优案例 http://blog.itpub.net/23718752/viewspace-1172818/ 啰嗦了一大堆,就是想说明脚本复审的重要性,可能开发和dba进行脚本审查的角度不一样,开发侧重于业务,dba侧重要系统。可能结合起来效果就好一些。 举一个例子。 今天开发找我复审一些一个补丁脚本,需要修复一些数据,他们的思路就是创建一个临时的表(不是临时表),然后给临时表加个索引,和一个大表进行关联update,update结束后,把这个临时的表给删除。 create table temp_c_rate_fix_expr_date as select rc_rate_seq_no,expiration_date,last_cyc_expr_date,(SELECT End_Date FROM Cycle_Control WHERE Cycle_Control.Cycle_Code=c_rates.Cycle_Code AND Trunc(expiration_date,'dd') BETWEEN Start_Date AND End_Date) shoudate, service_receiver_id FROM C_RATES WHERE sys_creation_date = to_date('20140818','yyyymmdd') and (expiration_date is not null or expiration_date != null) and (last_cyc_expr_date = null or last_cyc_expr_date is null);

create unique index temp_c_rate_1ux on temp_c_rate_fix_expr_date (rc_rate_seq_no,service_receiver_id) nologging ;

update ( select rc.last_cyc_expr_date OLD, tmp.shoudate NEW, rc.dl_update_stamp DL

from c_rates rc, temp_c_rate_fix_expr_date tmp

where tmp.rc_rate_seq_no = rc.rc_rate_seq_no and tmp.service_receiver_id = rc.service_receiver_id)

set OLD = NEW,

DL = :patch_id ; COMMIT ; drop table temp_c_rate_fix_expr_date; commit; 这个思路我不反对,其实也是蛮高效的,而且易于控制。 但是细细查看脚本,还是发现了一些问题 首先是关于null的部分,开发人员不是很理解null的用途,其实expiration_date != null这种语句是错误的,需要纠正一下。

代码语言:javascript
复制

create table  temp_c_rate_fix_expr_date as 
select  rc_rate_seq_no,expiration_date,last_cyc_expr_date,(SELECT End_Date FROM  Cycle_Control WHERE Cycle_Control.Cycle_Code=c_rates.Cycle_Code AND  Trunc(expiration_date,'dd') BETWEEN Start_Date AND End_Date)  shoudate,
service_receiver_id
FROM C_RATES WHERE sys_creation_date =  to_date('20140818','yyyymmdd') and (expiration_date is not null or expiration_date != null)
and (last_cyc_expr_date = null or  last_cyc_expr_date is  null);

还有因为这个表是一个临时表,所以只限于这个补丁部署中使用,可以采用nologging模式,性能要高很多。 因为表比较大,所以可以考虑加入并行。 所以这个部分的改进如下:

代码语言:javascript
复制

alter session force parallel ddl parallel  8;
create table temp_c_rate_fix_expr_date nologging as 
select  rc_rate_seq_no,expiration_date,last_cyc_expr_date,(SELECT End_Date FROM  Cycle_Control WHERE Cycle_Control.Cycle_Code=c_rates.Cycle_Code AND  Trunc(expiration_date,'dd') BETWEEN Start_Date AND End_Date)  shoudate,
service_receiver_id
FROM C_RATES WHERE sys_creation_date =  to_date('20140818','yyyymmdd') and (expiration_date is not null )
and  (last_cyc_expr_date = null  );

update的部分其实也可以好好斟酌一下。如果根据第一步创建的临时表,表中数据很少的时候,是可以考虑不用创建索引的。如果数据量大可以考虑创建索引。 最后一部分是删除临时表,可能开发对这个存在一定的误解。在drop 完成之后又使用了commit,这个是不必要的。 drop table temp_c_rate_fix_expr_date; commit; 可能看似很细小的错误,也可能引起很严重的问题。如果能在脚本上把把关,最后一道防线就是安全的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2014-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档