当前位置: 首页 > 图文教程 > 数据库 > Oracle > 解决Oracle性能优化中的问题

Oracle
oracle sys_connect_by_path 函数 结果集连接
oracle join on 数据过滤问题
Oracle 当前用户下所有表的记录总数
oracle 树查询 语句
oracle 触发器 实现出入库
Oracle 函数大全
oracle 删除重复数据
ORACLE 最大连接数的问题
oracle 层次化查询(行政区划三级级联)
oracle 查询表名以及表的列名
Oracle 数据显示 横表转纵表
oracle 服务启动,关闭脚本(windows系统下)
ORCLE 表中列的修改
oracle 数据库连接分析
Oracle 实现类似SQL Server中自增字段的一个办法
Oracle 常用的SQL语句
Oracle 数组的学习 小知识也要积累,养成好的学习态度
Oracle 日期的一些简单使用
Oracle 数据库连接查询SQL语句
Oracle DBA常用语句

解决Oracle性能优化中的问题


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-30   浏览: 121 ::
收藏到网摘: n/a

 在Oracle性能优化时,用exists替代in,用表链接替代exists,关于前者,一般效果比较明显,exists效率明显比in高,但是如果要想表连接的效率比exists高,必须在from子句中,将记录多的表放在前面,记录少的表放后面。

  关于select... bulk collect into ... limit ...或fetch... bulk collect into ... limit ...句型:

  在使用如上句型时,通常我们都会用for或forall循环进行insert/update/delete操作。

  for/forall循环方法有好几种,如

  第1种:

  


for tp in tmp.FIRST.. tmp.LAST loop .... end loop;

  第2种:

  


for tp in 1 .. tmp.COUNT loop .... end loop;

  第3种:

  


for tp in indecs of tmp loop .... end loop;

  上面的第1种方法有一个致使的弱点,就是在select... bulk collect into ... limit ...或fetch... bulk collect into ... limit ...没有取到数据时,如果没有exit,则第一种方法会报错:ORA-06502: PL/SQL: numeric or value error。因为tmp.FIRST访问不存在,为空值。必须对错误进行错误处理。而在嵌套的循环中,内层的循环是不能用exit的,所有必然遇到这种错误。

  第2种方法不会出现这种问题,第3种方法没有试过。

  借鉴网上的做法,给出一种使用绑定变量的批量删除数据的存储过程:

  


PROCEDURE RemoveBat2DjaRecords(参数)

AS type RowIdArray is table of rowid index by binary_integer;

 rowIds RowIdArray;

 BEGIN loop select rowid BULK COLLECT into rowIds from 表名 

where 查询条件 and rownum <= 1000; 

exit when SQL%NOTFOUND; 

forall k in 1 .. rowIds.COUNT

 delete from 表名 where rowid = rowIds(k); 

commit

end loop;

 EXCEPTION when OTHERS then rollback

END RemoveBat2DjaRecords;

  上面的1000条是一个可以设定的数,根据你的服务器性能可以扩大或缩小。

用exit跳出循环,通常情况下,exit只跳出当前层的循环,与其它程序设计语言的break语句类似。在嵌套的循环中,如果要直接从内层循环跳出外面多层的循环,可使用'EXIT 标签 When'形式的语句,举例如下:

  


SQL> BEGIN 

2  <> 

3 FOR v_outerloopcounter IN 1..2 LOOP 

4   <> 

5 FOR v_innerloopcounter IN 1..4 LOOP

 6 DBMS_OUTPUT.PUT_LINE('Outer Loop counter is ' 

7 || v_outerloopcounter || 

8 ' Inner Loop counter is ' || v_innerloopcounter);

 9 EXIT WHEN v_innerloopcounter = 3; 

10 END LOOP innerloop; 

11 END LOOP outerloop; 

12 END; 

13 / 

Outer Loop counter is 1 Inner Loop counter is 1

 Outer Loop counter is 1 Inner Loop counter is 2 

Outer Loop counter is 1 Inner Loop counter is 3

 Outer Loop counter is 2 Inner Loop counter is 1 

Outer Loop counter is 2 Inner Loop counter is 2 

Outer Loop counter is 2 Inner Loop counter is 3 

PL/SQL procedure successfully completed.

  从上面可以看出,普通情况下,exit只跳出当前层的循环。


SQL> BEGIN 

2 <> 

3 FOR v_outerloopcounter IN 1..2 LOOP

 4 <> 

5 FOR v_innerloopcounter IN 1..4 LOOP 

6 DBMS_OUTPUT.PUT_LINE('Outer Loop counter is ' 

7 || v_outerloopcounter || 

8 ' Inner Loop counter is ' || v_innerloopcounter); 

9 EXIT outerloop WHEN v_innerloopcounter = 3; 

10 END LOOP innerloop; 

11 END LOOP outerloop; 

12 END; 

13 /

 Outer Loop counter is 1 Inner Loop counter is 1

 Outer Loop counter is 1 Inner Loop counter is 2 

Outer Loop counter is 1 Inner Loop counter is 3 

PL/SQL procedure successfully completed.

  从上面可以看出,exit跳出了外层的循环