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

Oracle
Oracle数据库的安全策略
ORACLE应用经验(2)
在ORACLE移动数据库文件
Microsoft SQL Server 安全问题
Oracle数据库技术(37)
Oracle数据库技术(38)
Access2000迁移到Oracle9i要点
数据库Oracle数据的异地的自动备份
安装Oracle加载数据库错误areasQueries的解决
Oracle数据库逻辑备份的SH文件
Oracle常见错误诊断
Oracle9i在Win2k环境下的完全卸载
Oracle数据库快照的使用
Oracle9i数据库异常关闭后的启动
Oracle也有注入漏洞
Oracle9iPL/SQL编程的经验小结
oracle用什么SQL语句判断表存不存在
Oracle SQL性能优化系列学习三
用Oracle并行查询发挥多CPU的威力
oracle快速删除重复的记录

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


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