1) 3种游标循环性能
a) 单条处理
declare
cursor 游标 is
begin
open 游标;
LOOP
FETCH 游标 INTO 变量;
EXIT WHEN 条件;
END LOOP;
CLOSE 游标;
end;
逐条处理,效率之低,不敢想象。
b) 批量处理
declare
cursor 游标 is
begin
open 游标;
FETCH 游标 BULK COLLECT INTO 变量;
EXIT WHEN 条件;
CLOSE 游标;
end;
一次FETCH出来.一次处理所有行,效率最高。
declare
cursor c is
select *
from table1;
type c_type is table of c%rowtype;
v_type c_type;
begin
open c;
loop
fetch c bulk collect
into v_type limit 100000;
exit when c%notfound;
<<inner1>>
begin
forall i in 1 .. v_type.count
insert /*+append*/
into table2
values v_type
(i);
commit;
EXCEPTION ----出错后忽略继续执行
WHEN OTHERS THEN
null;
end inner1;
end loop;
close c;
commit;
end;
--删除
delete from table2 where read_id = v_type(i);
c) 游标for循环
for c in (sql语句) loop
……
end loop;
效率非常接近于批量处理,这种隐式循环的游标语句,其实也是一种批量处理的过程,它每次读取了近100行数据到缓存.
d) 结论:在不使用集合变量(bulk collect into)的情况下,选择隐式游标,既简洁又高效。
http://www.2cto.com/database/201307/224636.html
2) 多用commit
在确保完整性的情况下多用commit提交,可以释放事务所占的资源,包括redo缓存、undo表空间、锁、管理这些资源的内部花费。
大表进行insert,update,delete时可以分批进行,小批量提交。
3) exists与in
a) 示例:select * from A where exists (select 1 from B where A.id = B.id)
b) 原理:通过使用EXISTS,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项;Oracle在执行IN时,首先执行子查询,并将获得的结果存放临时表中,再执行主查询。
c) 在选择了合理的驱动表情况下,基于CBO时,A、B两表数据量差别越大,exists的性能越好。在RBO/11g时代,exists与in在性能上是一样的,经过cost最低转换之后都采用了hash join的连接方式,影响性能的关键因素在于能否选择合适的驱动表。
d) 结论:在RBO/11g中还是尽量采用exists,RBO是基于统计信息的,一旦统计信息没有及时更新,就会出现性能问题。
4) not in和not exists
a) 在RBO/11g中,都采用hash join方式,子查询的数据量越大,not exists的效率越高,not exists子查询中可以使用索引,但是 not in的子查询中无法使用索引,在都不使用索引的情况下,not in与not exists无性能差别。
b) 空值null的影响:当外层表存在空值时,not in直接忽略此空值,not exists不会受影响,正常数据。当内层表为空时,not in导致返回的最终查询结果为空,not exists则不受影响。
c) 结论:不管是出于性能方面,还是防止null值干扰输出结果方面,建议尽量使用not exists
5) nologging
只有在如下情况下,nologging才会生效,普通的DML语句无效。
a) direct load (SQL*Loader)(load文件、load命令形式)
b) direct load INSERT (using APPEND hint)(模拟直接加载)
c) create table XXX nologging as select * from ……;
d) insert /*+ APPEND */ into xxx nologging ……;
e) create index …… nologging;
f) create table name as select与insert into在nologging状态下性能相当,但是在正常情况下,create由于其为DDL操作,日志量很少,故性能最好,因此可能的情况下,尽量选择create。
g) 一般情况nologging、append、parallel同时使用会大幅提高性能。