1、PL/SQL的性能优势
A、过程化的方法:SQL是非过程化语言,而PL/SQL是过程化语言,可操作优化器读取等;
B、减少网络开销:在客户端-服务器环境中,减少网络传输可以显著地提高性能;
C、分解并攻克海量SQL语句:SQL语句越很杂越难以优化,可以用PL/SQL分解,单独优化。
2、衡量PL/SQL的性能
A、下面的查询列出了SQL语句,它包含PL/SQL的执行时间,PL/SQL占总的SQL执行时间的比例和语句占数据库中所有PL/SQL开销的比例:
select sql_id, substr(sql_text,1,500) as sql_text,
round(relapsed_time/1000) as elapsed_ms,
round(plsql_exec_time/1000) plsql_ms,
round(plsql_exec_time*100/elapsed_time,2) pct_plsql,
round(plsql_exec_time*100/sum(plsql_exec_time) over(), 2) pct_total_plsql
from v$sql
where plsql_exec_time > 0 and elapsed_time >0
order by plsql_exec_time desc;
B、PL/SQL剖析器,DBMS_PROFILER找出代码中最耗资源的行
例:我们要分析NOCOPY_TEST包中的一个程序:
DECLARE
returncode binary_integer;
begin
returncode := dbms_profiler.start_profiler('Profiler Demo 2'),
nocopy_test.test_copy(400,1);
returncode := dbms_profiler.stop_profiler;
dbms_output.put_line('Profiler.returncode = '||returncode);
commit;
end;
C、11G的分层剖析器
3、数据访问优化--动态SQL和绑定变量的运用
4、代码优化
10G开始PLSQL_OPTIMIZE_LEVEL参数控制ORACLE可应用于PL/SQL程序的自动优化行为。有时,这些优化等价于重写PL/SQL代码。
这个参数可以取如下值:
0--不优化;
1--较少的优化,没有太大的调整;
2--(默认)明显的调整,包括循环优化和自动BULK COLLECT;
3--(仅用于11G)更进一步优化,包括自动内联子程序。
A、避免不必要的循环迭代;只要工作完成就立即使用EXIT语包退出循环。
B、将可能性最小的条件放在AND表达式的左边,如果它是错误的,ORACLE就没有必要计算第二个表达式的值;
例:IF t_amount(i) > i and t_time < '01-jun-98' then ... end if;
因为几乎所有金额都大于1,但仅有很少的发生在1988年6月之前,如果上面表达式反转,可以减少PL/SQL大约1/3的执行时间。
C、将可能性最大的条件放在OR表达式的左边,如果它是正确的,ORACLE就没有必要计算第二个表达式的值
D、将IF或CASE语句中的条件按可能性最大到最小的顺序排列,可以减少需要的次数以帮助获得性能提升。
E、避免深度地递归方法,迭代方法通常总是比递归性能更好,而且使用内存高效得多。
F、当给函数或过程传递很大的PL/SQL表作为参数时,考虑使用NOCOPY子句
p_input_table in out nocopy number_tab_type;
5、其它优化
5.1 内联PL/SQL---是一种被很多优化编译器用来提升代码性能的技术。内联从子程序中抽取代码然后插入,内联到调用代码中
可以用 pragma inline(函数,'YES')实现内联或参数PLSQL_OPTMIZE_LEVEL设为3自动内联
5.2 数据类型---PLS_INTEGER和SIMPLE_INTEGER比NUMBER运算更快。当合适的时候使用PLS_INTEGER和SIMPLE_INTEGER优化PL/SQL的整数计算。
5.3 当进行大量数字计算时,JAVA存储过程的性能比直接使用PL/SQL要优化很多。而当使用高效的数据类型和本地编译时,该优势会减弱。
5.4 DML触发器的性能
Create or replace trigger sales_apd
before update of amount_sold or insert
on sales
for each row
when (new.amount_sold> 1500)
declare
....
利用create trigger语句的of过去和when子句,以确保触发器仅在必要时触发。