常用的PL/SQL开发原则
(1)广泛使用绑定变量,特别是批量绑定,因为这可以有效的避免sql的硬解析和PL/SQL引擎和SQL引擎的上下文切换!
(2)广泛使用UROWID来处理DML语句(UROWID是ROWID扩展,ORACLE推荐使用UROWID来替代ROWID)
(3)在你的存储过程中谨慎使用DDL语句(create、alter、drop、truncate等),因为这可能会破坏你的transaction的连续性,更为严重的是可能会阻塞DML操作并可能会导致大量library cache latch争用并且有可能会导致某些sql执行计划的改变。
(4)不要在存储过程里不应该commit的地方commit,特别是当你的存储过程会被另外一个存储过程调用的时候,你考虑到了你这么做会破坏调用你的父存储过程的transaction的连续性了吗?
(5)注意你面对的数据量,小数据量的处理方法和海量数据的处理方法是不一样的!
(6)循环的时候要注意清空临时变量的值
(7)注意“select into 变量”的问题,使用子begin语句封装“select into 变量”以避免可能会出现的错误,这样就可以避免要在“select into 变量”之前先执行一下select count(*)
(8)不要让oracle执行你的PL/SQL代码时产生隐式转换
(9)在PL/SQL中定义varchar2变量的时候当你在不知道你所定义的变量的长度的时候可以将其定义为varchar2(4000),这一点都不浪费!
(10)如果你写的一组存储过程有逻辑上的关联,那我建议你要把这些存储过程封装到一个package里面
(11)改正你的PL/SQL代码里的所有编译时编译器提示出的warning
(12)循环的时候一定要注意exit,否则就太可怕了!
(13)处理显式cursor的时候一定要注意fetch和exit,否则就太可怕了!如下是我处理的一个真实的案例,这个案例中暴露出的问题就很好的说明了处理cursor的时候一定要注意fetch和exit:
今天下午1点多的时候接到同事的一封信,信里提到我们的一个10gR2的开发环境连不进去了,报这样的错“ORA-00257:archiver error.Connect internalonly,until freed.”。很明显是因为归档进行不下去而导致整个系统被hang住了。
我上去一看,果然是存放归档日志的目录满了。上述开发环境的存放归档日志的目录大小为10个G,alert log显示从今天11点半开始到下午1点左右的这段时间系统整整产生了10个G的归档日志,而且还在源源不断的继续产生。在继续产生归档日志的时候因为空间满了,所以导致整个系统被hang住。原因知道了,处理过程就很清晰了。
只保留一个归档日志,然后手工把所有其他的归档日志rm掉,注意这里不要一下子就把所有的归档日志给rm掉,否则可能导致文件系统的句柄无法释放,进而这些归档日志占用的空间也无法释放。然后run一个ADDM报告,看一下是什么导致了在这么短的时间内产生了这么多的归档日志。从ADDM报告中可以很清晰的看到产生这么多归档日志的根本原因是因为一个存储过程里的几条sql在短时间内执行了1400多万次的缘故。
用alter system kill session配合kill -9杀掉这个存储过程所在的session,以阻止它源源不断的产生归档日志。
接着我分析了一下上述存储过程,发现根本原因在于在这个存储过程里打开了一个cursor,fetch这个cursor中的一条记录到一个record里,然后开启一个循环,在循环里run上述的那几条sql语句。但致命的是在循环的末尾并没有再fetch这个cursor中的另外一条记录,这就导致了上述循环的条件永远为真,所以上述sql如果不被我中断的话就会永远执行下去。这也就解释了为什么会在短时间里产生了大量的归档日志,并且undo tablespace的空间也被消耗殆尽。后续处理过程这里省略……
(14)bulk collect into的时候不要一次collect太多的数据,建议一次collect的数据量在10000条以内,你可以用批量绑定自带的limit子句来限制或者使用rownum来限制
(15)如果你使用了批量绑定,那为什么要把时间浪费在写诸如insertinto tablename(column1,column2,……,column100) values(value1(i),value2(i),……,value100(i))这样的sql语句上面?如果有可能,就写一个你自己的存储过程代码生成器吧,让它来帮你生成这样的语句。你应该把精力集中在更有用的方面!
(16)你希望你的代码被并发执行吗?如果你不希望或者你的代码根本就不能够被并发执行,那就想一个办法控制并发吧!在应用层面控制就好,比如在update之前先尝试对该记录加for update nowait的锁,或者利用DML语句当前读的特性来避免并发都是不错的主意
(17)不要写诸如insert into tablename1 select* from tablename2这样的语句,你考虑到扩展性了吗?假如以后tablename1或者tablename2增加或减少字段了呢?
(18)谨慎使用hint,除非你很清楚你在做什么。比如说这里你强制oracle使用了某个索引,假如以后这个索引的名字被改了,由此带来的执行计划的变更你怎么办?你考虑到这种情况了吗?
(19)注意关联更新丢失数据的问题,update语句如果没有指定where条件那就是对所有的数据做update操作,这个就太恐怖了!
(20)用好临时表,有时候临时表很有用!特别是在根据一堆复杂条件去更新海量数据的时候
(21)尽量避免在存储过程里使用递规!不是说不能用递规(递规在某些特定的情况下很有用),而是说在用递规的时候一定要避免无限递规的情况!
(22)写好你的PL/SQL代码里的注释,这个很重要!不写注释并不代表你很厉害!
常用的PL/SQL开发原则的更多相关文章
- ORACLE PL/SQL开发--bulk collect的用法 .
刚刚在inthirties老大的博客里看到这篇文章,写的不错,正好自己最近在学习PL/SQL,转过来学习学习. ============================================ ...
- PL/SQL开发中动态SQL的使用方法
一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...
- Oracle PL/SQL开发基础(第三十三弹:EXCEPTION_INIT)
如果有一些异常并没有异常名称,比如一些ORA-开头的异常并没有一个友好的预定义的异常定义,此时在WHEN子句中无法使用具体的异常名称,必须要使用OTHERS异常处理器进行捕捉.通过EXCEPTION_ ...
- PL/SQL开发五年工作经验精典实例
1. minus(差集)与intersect(交集) minus指令是运用在两个SQL语句上.它先找出第一个SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中,如果有的话,那这一笔 ...
- Oracle PL/SQL开发基础(第三十四弹:RAISE_APPLICATION_ERROR)
RAISE_APPLICATION_ERROR在子程序内部使用时,能从存储子程序中抛出自定义的错误消息.这样就能将错误报告给应用程序而避免范围未捕获异常. 语法如下: RAISE_APPLICATIO ...
- Oracle SQL Developer,Oracle 开发工具之toad、SQL Developer、PL/SQL Developer等比较
参考: oracle 的几个开发工具比较 因Oracle几乎是中大型商业企业数据的首选,所以比较一下常用与Oracle的工具. Oracle SQL Developer 免费,一般开发使用足矣,常用. ...
- PL/SQL数据开发那点事
PL/SQL开发那点事----->PL/SQL开发过程中异常处理 用户编写的PL/SQL块在执行过程中不可避免地要发生一些错误. 这里涉及的错误并不是由于程序的语法错误引起的,而是因为处理的数据 ...
- PL/SQL存储过程编程
PL/SQL存储过程编程 /**author huangchaobiao *Email:huangchaobiao111@163.com */ PL/SQL存储过程编程(上) 1. Oracle应用编 ...
- 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》
本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...
随机推荐
- Linux显示中文乱码解决方法
vi /etc/sysconfig/i18n 将内容改为 LANG="zh_CN.GB18030" LANGUAGE="zh_CN.GB18030:zh_CN.GB231 ...
- 使用异步 I/O 大大提高应用程序的性能
使用异步 I/O 大大提高应用程序的性能 学习何时以及如何使用 POSIX AIO API Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出之后,应用程序就会阻 ...
- A Step-by-Step Guide to Your First AngularJS App
What is AngularJS? AngularJS is a JavaScript MVC framework developed by Google that lets you build w ...
- Mac OS X 快捷键(完整篇) 转载
转载自:http://www.nooidea.com/2011/01/mac-os-x-keyboard-shortcuts.html 快捷键是通过按下键盘上的组合键来调用 Mac OS X 功能的一 ...
- (转)开源爬虫larbin分析
转自风中之炎的博客:http://www.cnblogs.com/FengYan/archive/2012/02/04/2338630.html 1. larbin简介(百度百科) larbin是一种 ...
- POJ 3277 City Horizon(叶子节点为[a,a+1)的线段树+离散化)
网上还有用unique函数和lowerbound函数离散的方法,可以百度搜下题解就有. 这里给出介绍unique函数的链接:http://www.cnblogs.com/zhangshu/archiv ...
- HttpWebRequest和HttpWebResponse
原文:http://blog.csdn.net/haitaofeiyang/article/details/18362225 申公前几日和一个客户做系统对接,以前和客户对接一般采用webservice ...
- hdu 4315 Climbing the Hill 博弈论
题意:有n个人爬山,山顶坐标为0,其他人按升序给出,不同的坐标只能容纳一个人(山顶不限),Alice和Bob轮流选择一个人让他移动任意步,但不能越过前面的人,且不能和前面一个人在相同的位置.现在有一个 ...
- NET权限系统开源项目
http://www.cnblogs.com/yubaolee/p/OpenAuth.html http://www.cnblogs.com/guozili/p/3496265.html Sereni ...
- mysql表的一对一/一对多/多对多联系
1.数据库中的多对多关联关系一般需采用中间表的方式处理,将多对多转化为两个一对多. 2.通过表的关系,来帮助我们怎样建表,建几张表. 一对一 一张表的一条记录一定只能与另外一张表的一条记录进行对应,反 ...