Archive for the ‘oracle’ Category

绑定变量

这个问题是个“重中之重”的问题,对于我们这些做OLTP(联机事务处理,特点是并发多,事务短)系统的朋友来说,尤为要重视这个问题;我见过周围太多的了,都没有意识到这个问题的重要性;我自己能做到“洁身自好”,基本在项目开发的时候,不用任何硬编码,但如果合作者大量使用了硬编码,就让我“前功尽弃”;这个问题一直是我心中的痛; 什么绑定变量?举个简单的例子: Select * from tab1 wher f1=:f1 这样的语句就是绑定变量的语句,:f1对应的值可以为任何值,比如’a’,’ab’,’abc’; 无论为什么值,内部只要解析一次, 如果不用绑定变量,就是硬编码: 比如: Select * from tab1 wher f1=’a’ Select * from tab1 wher f1=’ab’ Select * from tab1 wher f1=’abc’ 这3句话,Oracle就要解析3次,而且随着f1这个字段值不断地变化,解析的次数是“无限”的; 什么是解析?简单的说分两步: 1. 判断sql语句是否合法,表或字段等信息数据字典是否正确等; 2. 生成执行计划树,这个步骤是关键,就比如每天早上从家到公司上班,有很多条路线,选择一条性价比最好的路线; 如果是硬编码,每次执行SQL的时候,这个解析都得重做一遍,这个是很大的“资源浪费”; oracle 所有执行的语句都要放在服务器的一个内存里(SGA的shared_pool), 如果是绑定变量的SQL,变量无论怎么变化,它在这个内存里只占用一次,而如果是硬编码,where条件的值每变化一次,就会申请一个新的内存块存储,oracle这么做的目的是:“好心”让你这个SQL的解析以后有机会再被用到,避免了重复解析,而硬编码机会很难有机会复用

用procedure 还是package

package相对于procedure 有这几个优点: a. 结构清晰,如果全部是过程,那么稍微复杂点的系统就会有数千个过程,感觉很乱,如果用包,可以把相关业务合并,把数千个合并成数百个,结构清晰,查阅方便; b. 命名方便,有点类似于java或C#里的namespace;特别是业务逻辑多了,没有分类,命名容易冲突 c. 功能更强些,比如如果输出cursor(在前台程序一般叫DataSet),用procudure好像是不能实现的,而且嵌入java等些高级应用,package也更容易点; d. 对于很简单的相关业务点,用独立的过程感觉很浪费,比如我们做个设备跟踪的操作,假如有十个点,每个点都做很少的操作,这样就要写10个过程,每个过程就那么两三句话,这时候用package就非常合适,一个package里内嵌10个小过程,看上去比写10个独立的小过程更舒服些,关键可读性好多了,关联的业务点都放在一起了;容易维护和让别人查阅; e. 面向对象更好,可以做到overload等一些面向对象的特性; f. 包加密方便,因为包分package和package body两部分,package 只是申明内部函数或过程名已经全局变量;package body 实现具体函数或过程的脚本; 所以我们加密的时候只要对package body加密;package留给别人查阅,让他们清楚如何在前台程序里调用这些包里的函数和过程,这是“一箭双雕”的事情; 而在独立过程或函数上,就没法两者兼顾;oracle自己内部的包也都是这种模式; g. 看看ORACLE自己,倾向于使用哪个,我们可以借鉴它的做法; 通过查看(11g的版本),发现sys用户的PROCEDURE, FUNCTION,PACKAGE的数量分别为72,96,595(嵌入的过程或函数有10344个),包的逻辑对象数量占有98.4%;只有1%多的对象是独立的过程和函数;

尽量使用%type作为参数和变量类型

很多人一直写T-SQL的存储过程写惯了,没留意PL/SQL这么好的功能,建议一定要用; 比如 单号类型,在T-SQL里,只能定义成 v_bill_type varchar(20); 这样定义的缺点就是把类型“钉死”了;万一以后修改表结构,把bill_type的字段类型修改成number或是其他的,这就就不会自动“跟着更新”; 所以最好写成 v_bill_in_type bill_in_mt.bill_in_type%TYPE; 不过据说直接写类型,程序运行效率更好些,我想即使有效率损失,这么一点点也无所谓吧; 还有记录类型 %rowtype也是个很不错的东西,否者按字段定义,就要定义几十个变量才抵一个%rowtype;

试试访问速度?