要养成为程序和关键模块加注释的习惯,在SQL中插入注释有助于辨别查询在程序中的位置。
这些注释在插叙哦是非常有用。注释也有助于判断单独应用对服务器造成的负载有多大。
oracle的dbms_application_info包,它支持48字节的模块明后名称、32个字节的动作名称和64个字节的客户信息,在oracle环境下,可以利用这个程序包记录在哪个应用正在执行,以及他在何时正在做什么。
尽量减少分别连接数据库次数。
将预更新的数据填入数组,这样就尽可能减少了程序和数据库核心间的交互次数,从而使性能产生了另一次飞跃。
原因:
1.在于数据库连接是很重的操作,消耗资源很多。
客户端与远程服务器的监听程序建立联系;
监听程序要么创建一个进程或线程来执行数据库核心程序,要么直接或间接的把客户请求传递给已存在的服务器进程,这取决于此服务器是否为共享服务器。
除了这些系统操作(创建进程和线程并开始执行)之外,数据库系统还必须为每个session建立新环境,以跟踪它的行为。建立新session前,DBMS还要执行登录触发器,还要初始化存储过程和程序包。上面这些还不包括客户端进程和服务器进程之间要完成的握手协议。正因为如此,连接池等保持永久数据库连接的技术对性能才如此重要。
2程序(甚至包括存储过程)和数据库之间的交互也有开销。
即使数据库连接已经建立且扔未中断,程序和DBMS核心之间的上下文切换也有代价。
物化视图是某时间点的数据副本。
在应用程序中使用数据定义语言(DDL)建立、修改或删除数据对象,是很差的方式。
DDL的作用是以核心数据库的数据字典为基础的,数据字典是所有数据库操作的中心,所以任何对数据字典的操作都会引起全局枷锁,对系统性能影响巨大。唯一可接受的DDL操作是对表的truncate(清空)操作,它能极快地清空表的所有数据(记住,truncate table不可通过回滚回复)。
不应再程序中进行数据库对象的建立、修改及删除等操作,虽然设计应用时要考虑这些问题。
永久表可以设置非常复杂的存储选项,而临时表不能。临时表的索引可能不是最优的,因此,查询临时表的语句效率比永久表的差。另外,查询之前必然先为临时表填入数据。
如果一定要用临时表,应确保数据库知道哪些表是临时的。
SQL完全基于集合(set)来处理数据。
一次将大批量数据的处理分割成多次小块处理效率低:
1.占用过多的空间保存原始数据,以备事务回滚。
2.万一修改失败,回滚消耗过长的实践。
不要认为在进行大规模修改操作时,应该在操作数据的代码中有规律的多安排些commit命令。严格从实践的角度讲,“从头开始重做”比“确定失败发生的时间和位置接着已提交部分重做”要容易的多,简单的多,也快的多。
避免SQL中引入“过程逻辑”的主要原因:
1.数据库访问,总会跨多个软件层,甚至包括网络层。
即使没有网络访问,也会涉及进程间通讯;额外的存取访问意味着更多的函数调用、更大的宽带,以及更长的等待时间。
2.在SQL中引入过程逻辑,意味着性能和维护问题应该由你的程序承担。
优化器对自定义函数的代码苏能为力。
oracle的bulk collect子句,一次性将两个值放到数据中,
select slosure_date
bulk sollect into dtPerStaArray
from tperrslt
where relt_period in ('1' || to_char(Param_dtAcc,'MM'),
'9' || to_char(Param)dtAcc,'MM"))
order by rslt_period;
放到两个变量中。
select max(decode(subset(reslt_period,1,1),
'1',closure_date,
to_date('14/10/1066','DD/MM/YYYY'))),
max(deocode(substr(reslt_period,1,1),
'9',closure_datte,
to_date(14/10/1066','DD/MM/YYYY'))),
into dtPerSta,dtPerClosure
form tperrslt
where fiscal_year=to_char(Param_dtAcc,'YYYY')
and rslt_period in ('1' || to_char(Param_dtAcc,'MM'),
'9' || to_char(Param_dtAcc,'MM'));
重复键的探索,唯一性如何保证?
我们几乎总是建立一个唯一索引,每次向该索引增加一个键时,都要检查是否违反了该唯一性索引。然而,建立索引项需要记录物理地址,于是就要求先将记录插入表,后将索引项插入索引。如果违反了此约束,数据库会取消不完全的插入,并返回违反约束的错误信息。
上述这些操作开销巨大,但最大的问题是,整个处理必须围绕个别异常展开,于是我们必须“从个别记录的及年度进行思考”,而不是“从数据集出发进行思考”,这与关系数据库理论完全背道而驰。多次违反此约束会导致性能严重下降。
translate 语法:TRANSLATE(char, from, to) 用法:返回将出现在from中的每个字符替换为to中的相应字符以后的字符串。 若from比to字符串长,那么在from中比to中多出的字符将会被删除。 三个参数中有一个是空,返回值也将是空值。 举例:SQL> select translate('abcdefga','abc','wo') 返回值 from dual; 返回值 ------- wodefgw 分析:该语句要将'abcdefga'中的'abc'转换为'wo', 由于'abc'中'a'对应'wo'中的'w', 故将'abcdefga'中的'a'全部转换成'w'; 而'abc'中'b'对应'wo'中的'o', 故将'abcdefga'中的'b'全部转换成'o'; 'abc'中的'c'在'wo'中没有与之对应的字符, 故将'abcdefga'中的'c'全部删除; 简单说来,就是将from中的字符转换为to中与之位置对应的字符, 若to中找不到与之对应的字符,返回值中的该字符将会被删除。 在实际的业务中,可以用来删除一些异常数据, 比如表a中的一个字段t_no表示电话号码, 而电话号码本身应该是一个由数字组成的字符串, 为了删除那些含有非数字的异常数据, 就用到了translate函数:delete from a, where length(translate(trim(a.t_no), '0123456789' || a.t_no, '0123456789')) <> length(trim(a.t_no));