当前位置: 首页 > 图文教程 > 数据库 > Oracle > 数据库Oracle性能优化可能出现的问题

Oracle
常见的一些Oracle初学者的问题
ORACLE认证系统概述
数据库考试简介:Oracle认证
Oracle认证基础知识介绍
ADO连接Oracle Access示例及记录集处理源码
SQL Server和MySQL的安全性分析
用Oracle和SQL Server数据库组合利弊分析
Oracle 11g分区功能新革命
Flashback Query 恢复误删除的数据
基于Oracle高性能动态SQL程序开发
怎样在Oracle 9i中正确的转换时区
Oracle 10g导出的数据库能否导入Oracle 9i?
增加Distinct后查询效率反而提高
Oracle限制返回结果集的大小
Java语言数据库操作的基本流程
美国甲骨文(ORACLE)公司入驻渝中区大都会商厦
RHEL AS4上安装oracle 10R2 的方法
DB中如何查询Table占用空间的大小
编写高质量高性能的MySQL语法
Oracle数据库自动备份的具体实现步骤

数据库Oracle性能优化可能出现的问题


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-30   浏览: 31 ::
收藏到网摘: 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跳出了外层的循环