oracle笔记整理13——性能调优之SQL优化

本文介绍了几种提升SQL性能的方法,包括游标循环的优化、合理使用commit、exists与in的区别、not in与not exists的选择、nologging的应用场景、减少远程访问及优化索引等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 selectinsert into在nologging状态下性能相当,但是在正常情况下,create由于其为DDL操作,日志量很少,故性能最好,因此可能的情况下,尽量选择create。
g)  一般情况nologging、append、parallel同时使用会大幅提高性能。

6) 减少远程访问及次数

7) 先删索引,再插数据,最后重建索引(建并行索引,之后再alter parallel为1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值