`
nzhzds
  • 浏览: 39916 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
最近访客 更多访客>>
社区版块
存档分类
最新评论

PL/SQL性能

阅读更多
本文摘着网友岁月留痕《有关使用PL/SQL提高性能的学习》

1、使用rowid进行跌代处理,通过rowid检索数据是最快的方法,甚至比唯一参考索引还快。
如果在循环中需要根据cursor取到的条件进行进一步的操作,则在cursor中同时取出rowid,并且根据rowid定位记录会是个高效率的方法,比取到主键或者唯一性索引的效率都好。
以下的例子是取表的10万条记录进行后续处理,id是该表的主键。优化后节省将近2秒钟,效率提升16%。
优化前:
declare
   cursor cur_test is
   select id from user_tab
   where rownum <= 100000;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in cur_test loop
      update user_tab
      set user_name = user_name
      where id = n_row.id;
     
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
20050420 10:40:14.791
20050420 10:40:26.509
PL/SQL procedure successfully completed.
优化后:
declare
   cursor cur_test is
   select rowid from user_tab
   where rownum <= 100000;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in cur_test loop
      update user_tab
      set user_name = user_name
      where rowid = n_row.rowid;
     
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
20050420 10:40:38.112
20050420 10:40:48.051
PL/SQL procedure successfully completed.
2、确保比较运算中的数据类型相同。
要确保在where条件中的等号左右的数据类型是一致的,否则oracle虽然会进行自动的转换,但是效率上会有所缺失。
3、根据条件出现的频率来排序IF条件。
如果在块儿中间有多个IF条件判断,则应该考虑将命中率高的IF条件放在前面,这样对效率的提升也是有好处的。
下面的例子循环1亿次,判断条件的次序调整,节省将近4秒钟,效率提升23%。现在判断条件后只是进行简单的累加,如果是做更复杂的处理,效率的提升会更明显。
优化前:
declare
   ln_number number := 0;
   ln_if number := 0;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..100000000 loop
      if ln_if = 1 then
         ln_number := ln_number + 1;
      elsif ln_if = 0 then
         ln_number := ln_number + 2;
      end if;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 10:56:44.411
20050420 10:57:01.062
PL/SQL procedure successfully completed.
优化后:
declare
   ln_number number := 0;
   ln_if number := 0;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..100000000 loop
      if ln_if = 0 then
         ln_number := ln_number + 1;
      elsif ln_if = 1 then
         ln_number := ln_number + 2;
      end if;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 10:57:01.498
20050420 10:57:14.385
PL/SQL procedure successfully completed.
4、使用PLS_INTEGER PL/SQL数据类型进行整数运算。
这种数据类型可以用于代替各种数值数据系列类型的声明中,只要变量的值是一个整数,且在-2147483647到+2147483647。该数据类型可以使用更少的内部命令来处理,因此用这种数据类型可以提高性能。
这种数据类型可以替代整数的NUMBER型的变量定义,而实际的处理效率是比NUMBER型更快捷的。
以下的例子是个简单的迭加,循环1亿次,使用该数据类型节省大概0.5秒的时间,效率提升16%,不知道对于更复杂的数据处理,是不是效率上会有更大的提升。
优化前:
declare
   ln_number number;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..100000000 loop
      ln_number := ln_number + 1;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 10:47:17.676
20050420 10:47:21.301
PL/SQL procedure successfully completed.
优化后:
declare
   ln_number pls_integer;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..100000000 loop
      ln_number := ln_number + 1;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 10:47:21.989
20050420 10:47:25.149
PL/SQL procedure successfully completed.
5、减少对SYSDATE的调用
单独取SYSDATE的时候不再需要从dual表中获得,可以直接付给变量:
ld_date := sysdate;
但是应该减少调用SYSDATE的次数,如果可以,应该在块儿的最开始付给某个变量,而不是需要的时候再取得,除非你需要精确的时间戳。
下面的例子循环10万次,分别在循环中取得时间和循环外取得时间,节省时间0.152秒,效率提升99%。但是要注意这两个不是等价的优化,如果你需要每次循环取得不同的时间戳,就应该将按照前面的脚本编写。
优化前:
declare
   ld_date date;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..100000 loop
      ld_date := sysdate;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 11:32:41.432
20050420 11:32:41.586
PL/SQL procedure successfully completed.
优化后:
declare
   ld_date date;
   ld_date1 date;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   ld_date1 := sysdate;
   for n_row in 1..100000 loop
      ld_date := ld_date;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 11:32:42.218
20050420 11:32:42.220
PL/SQL procedure successfully completed.
6、减少MOD函数的使用,可以用其他函数代替,但是效率不同。
不是所有的oracle函数的效率支出是等同的,MOD就是个消耗会比较多的函数,虽然他的功能是不错的,但是如果可以用其他的函数取代,应减少该函数的使用次数。
下面的例子是进行了100万次循环,分别使用mod作为判断条件或者不使用,优化后节省0.7秒多,效率提升90%。
优化前:
declare
   ln_number pls_integer := 0;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..1000000 loop
      ln_number := ln_number + 1;
      if mod(ln_number,1000) = 0 then
         ln_number := ln_number + 2;
      end if;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 11:20:34.435
20050420 11:20:35.225
PL/SQL procedure successfully completed.
优化后:
declare
   ln_number pls_integer := 0;
   ln_num1 pls_integer := 0;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..1000000 loop
      ln_number := ln_number + 1;
      ln_num1 := ln_num1 + 1;
      if ln_num1 = 1000 then
         ln_number := ln_number + 2;
         ln_num1 := 0;
      end if;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 11:20:35.461
20050420 11:20:35.542
PL/SQL procedure successfully completed.
7、将参考表加载到PL/SQL表中可以加快查询速度。这是因为利用了PL/SQL中数组索引的优势。
下面这个例子是主表100万条记录,根据主键取参考表的对应字段,参考表只有6条记录。优化后的节省将近45秒,效率提升97%。
优化前:
declare
   cursor cur_test is
   select changecentsreason_id
   from usercentsdetails_tab
   where rownum <= 1000000;
  
   ls_name changecentsreason_tab.changecentsreason%type;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in cur_test loop
      select changecentsreason
      into ls_name
      from changecentsreason_tab
      where id = n_row.changecentsreason_id;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
20050420 10:21:09.461
20050420 10:21:55.407
PL/SQL procedure successfully completed.
优化后:
declare
   type ref_array is table of varchar2(20) index by binary_integer;
   ref_tab ref_array;
  
   cursor cur_test is
   select changecentsreason_id
   from usercentsdetails_tab
   where rownum <= 1000000;
  
   cursor cur_ref is
   select id,changecentsreason
   from changecentsreason_tab;
  
   ls_name changecentsreason_tab.changecentsreason%type;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row1 in cur_ref loop
      ref_tab(n_row1.id) := n_row1.changecentsreason;
   end loop;
  
   for n_row in cur_test loop
      ls_name := ref_tab(n_row.changecentsreason_id);
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
20050420 10:19:20.333
20050420 10:19:21.604
PL/SQL procedure successfully completed.
8、时间范围的取得
以前为了查询一整天的记录,我通常的写法是:
between to_date(sysdate) - 1 and to_date(to_char(to_date(sysdate),'yyyymmdd')||' 23:59:59','yyyymmdd hh24:mi:ss') - 1
多次的格式转换对性能也是有影响的,写成:
between to_date(sysdate) - 1 and to_date(sysdate) - 0.000011574
0.000011574表示1秒。这样的效率应该会有所提升。
下面的例子循环了100万次,优化后节省36秒多,效率提升89%。不过这是比较特别的情况,因为其实不需要在循环中这样做的,循环只是放大了效率提升的效果。
优化前:
declare
   ld_date date ;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..1000000 loop
      ld_date := to_date(to_char(to_date(sysdate),'yyyymmdd')||' 23:59:59','yyyymmdd hh24:mi:ss') - 1;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 11:24:19.530
20050420 11:24:50.525
PL/SQL procedure successfully completed.
优化后:
declare
   ld_date date ;
begin
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
   for n_row in 1..1000000 loop
      ld_date := to_date(sysdate) - 0.000011574;
   end loop;
   dbms_output.put_line(to_char(SYSTIMESTAMP,'yyyymmdd hh24:mi:ss.ff3'));
end;
/
20050420 11:24:50.750
20050420 11:25:05.229
分享到:
评论

相关推荐

    Oracle Sql Pl/Sql 性能优化 精华

    富士康MIS 资深人员总结的Oracle PL/Sql 性能优化心得 给新进员工学习之文档 &lt;br&gt;绝对精华 写出专业的Sql

    oracle10g_pl/sql

    6. **PL/SQL性能优化** - **绑定变量**:减少解析次数,提高执行效率。 - **存储优化**:合理使用索引、分区等技术提升查询速度。 - **事务管理**:理解COMMIT、ROLLBACK和SAVEPOINT,确保数据一致性。 7. **...

    Oracle PL/SQL程序设计(第5版)(套装上下册)

    《Oracle PL/SQL程序设计(第5版)(套装上下册)》不但介绍了大量的Oracle 11g的PL/SQL新性能,还提供了许多优化PL/SQL性能的新方法。  《Oracle PL/SQL程序设计(第5版)(套装上下册)》结构清晰,示例丰富,...

    pl/sql最新中文手册

    8. **索引和性能优化**:手册可能也会涉及如何利用索引来提高PL/SQL程序的执行效率,以及如何分析和优化SQL语句。 9. **并发和锁定**:在多用户环境下,理解并发控制和锁定机制是必要的。手册可能会讨论如何处理...

    一个对数据库的操作工具PL/SQLpl/sqL工具

    10. **性能优化**:PL/SQL可以利用Oracle的内置优化器,提高SQL查询的执行效率。 PLSQL7121363这个文件名可能是指PL/SQL工具的某个版本或特定的组件,具体的功能和特性可能需要根据实际的软件来解读。在实际工作中...

    pl/sql developer11.0

    PL/SQL Developer是一款由Allround Automations公司开发的专业Oracle数据库开发工具,专为编写、调试、测试和管理PL/SQL代码而设计。标题中的“pl/sql developer11.0”指的是该软件的第11个主要版本。在本文中,我们...

    Oracle PL/SQL实战(待续)

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL的数据处理能力与PL的程序设计特性,是Oracle数据库系统中用于创建存储过程、函数、触发器和包的主要工具。在这个"Oracle PL/SQL实战(待续)"的主题中,我们将深入...

    pl/sql 学习资料

    7. **PL/SQL性能优化**: -绑定变量:如何利用绑定变量提高查询性能。 -索引和分区:理解如何设计和使用索引来优化查询。 -PL/SQL代码优化技巧:避免不必要的计算,减少磁盘I/O,提高程序效率。 8. **PL/SQL与...

    Oracle PL/SQL程序设计(第5版)(下册)第二部分

    使用工具和技巧来优化PL/SQL性能,例如PL/Scope和PL/SQL中的层次化profiler。 ? 探讨了数据类型、条件控制语句和顺序控制语句、循环、异常处理、安全特性、全球化和本地化问题, 以及PL/SQL架构。 ? 通过使用过程、...

    pl/sql64位

    64位的PL/SQL开发者工具对于那些处理大数据量或者需要更高性能的用户来说尤其重要,因为它能够更好地利用现代计算机的内存和处理器资源。 在32位环境中,PL/SQL开发者工具可能受到内存限制,因为32位系统最大只能...

    oracle 9i pl/sql程序设计笔记

    ### Oracle 9i PL/SQL程序设计笔记精要 #### PL/SQL基础知识概览 **标题与描述**:本文档围绕“Oracle 9i PL/SQL程序设计笔记”这一核心主题,深入探讨了PL/SQL语言的基础知识及其在Oracle 9i数据库环境中的应用。...

    Oracle PL/SQL程序设计(第5版)(上下册)

    - **性能提升技术**:提供了一些具体的例子和最佳实践,展示了如何利用Oracle 11g的新特性来进一步优化PL/SQL程序的性能。 #### 八、实战案例分析 - **案例研究**:通过实际案例来演示如何综合运用前面章节所学的...

    oracle pl/sql从入门到精通 配套源代码

    8. **性能优化**:如何编写高效的PL/SQL代码,使用绑定变量、避免全表扫描、索引优化等技巧。 通过这本书的配套源代码,读者将有机会实际操作这些概念,加深对Oracle PL/SQL的理解,并提升数据库开发技能。每个示例...

    pl/sql 免安装,绿色版pl/sql

    5. **报表和图表**:PL/SQL Developer提供了一定的报表生成功能,可以生成关于数据库对象的各种统计报告,如表空间使用情况、索引分析等,为数据库性能优化提供参考。 6. **连接管理**:用户可以创建多个数据库连接...

    PL/SQL Developer 远程连接Oracle数据库

    8. **性能监控**:尽管是远程连接,PL/SQL Developer仍然可以显示执行计划、统计信息和性能指标,帮助分析和优化SQL查询。 9. **版本控制集成**:PL/SQL Developer可以与各种版本控制系统(如Git、SVN)集成,这...

    PL/SQL 基本知识

    存储过程是一组预编译的PL/SQL语句,可以被多次调用,减少了网络传输的开销,提高了性能。函数则返回一个值,常用于计算或数据转换。例如,在`jbpm.sql`文件中,可能包含了与业务流程管理(BPM)相关的PL/SQL存储...

    Oracle PL SQL程序设计 上 第五版(代码示例)

    《oracle pl/sql程序设计(第5版)》不但介绍了大量的oracle 11g的pl/sql新性能,还提供了许多优化pl/sql性能的新方法。 简单目录 《oracle pl/sql程序设计(第5版)(上册)》 (上册) 第1部分 pl/sql编程 第1章 pl/...

    Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发

    8. **索引优化和性能调优**:深入研究如何利用PL/SQL进行性能分析,以及如何通过索引、物化视图、表分区等手段提升查询性能。 9. **并发控制**:介绍PL/SQL中的锁定机制,如ROWLOCK和SHARE锁,以及如何避免死锁。 ...

    Oracle Database 12c PL/SQL开发指南 实例源代码

    9. **索引和性能优化**:了解如何创建和使用索引,以及通过PL/SQL分析和优化SQL查询性能。 10. **并发控制**:PL/SQL中的锁定机制,如ROW LEVEL LOCKING,以及如何处理死锁问题。 11. **错误处理和日志记录**:...

    PL/SQL doc 文件

    PL/SQL doc 文件 PL/SQL 是 ORACLE 对标准数据库语言的扩展,它被整合到 ORACLE 服务器和其他工具中,近几年中更多的开发人员和 DBA 开始使用 PL/SQL。本文将讲述 PL/SQL 基础语法、结构和组件、以及如何设计并执行...

Global site tag (gtag.js) - Google Analytics