Chinaunix首页 | 论坛 | 博客
  • 博客访问: 410359
  • 博文数量: 66
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 922
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-16 10:37
个人简介

高級Oracle DBA,善長Linux系統維運以及Oracle數據庫管理,開發,調優. 具有多年PL/SQL開發經驗.

文章分类

全部博文(66)

文章存档

2015年(9)

2014年(4)

2013年(5)

2010年(1)

2009年(3)

2008年(6)

2007年(30)

2006年(8)

我的朋友

分类: Oracle

2015-03-19 15:45:40

  有一個plsql函數,功能很簡單, 但是調用次數較多.
  之前寫的方式是select decode from dual方式, 改用case when直接return後,
  10萬測循環調用測試,耗時相差25倍.
   
  我的分析是: select會發生sql軟解析, SELECT 觸發SQL引擎與PL/SQL引擎間的上下文切換.
      在sqlplus中用set autotrace on分析,發現會有一個recursive calls,也證明了這一點.

  建議:變量能直接賦值的不需要用select val into xx from dual方式.
         decode用case when替換.

原始function的代碼類似如下:

点击(此处)折叠或打开

  1. SELECT DECODE(VREMARK,
  2.               '免測', '1',
  3.               '待測', '2',
  4.               '測試中', '3',
  5.               'PASS', '4',
  6.               '允收', '5',
  7.               'NG', '6',
  8.               'MARGINAL', '5',
  9.               'OK', '4',
  10.               '空')
  11. into v_mk
  12. from dual;
  13. return v_mk
修改後代碼:

点击(此处)折叠或打开

  1. return case VREMARK
  2.           when '免測' then '1'
  3.           when '待測' then '2'
  4.           when '測試中' then '3'
  5.           when 'PASS' then '4'
  6.           when '允收' then '5'
  7.           when 'NG' then '6'
  8.           when 'MARGINAL' then '5'
  9.           when 'OK' then '4'
  10.                else '空'
  11.           end ;
測試代碼:

点击(此处)折叠或打开

  1. declare
  2. v_start1 timestamp;
  3. v_end1 timestamp;
  4. v_start2 timestamp;
  5. v_end2 timestamp;
  6. v_xx varchar2(40) ;
  7. begin
  8.   v_start1 := systimestamp;
  9.   for r in 1..100000 loop
  10.      select FUNC_QM_LABLE_INFORM_MK('免測') into v_xx
  11.      from dual;
  12.   end loop;
  13.   v_end1 := systimestamp;
  14.   dbms_output.put_line('test1:');
  15.   dbms_output.put_line(v_end1-v_start1) ;


  16.   v_start2 := systimestamp;
  17.   for r in 1..100000 loop
  18.      v_xx := temp_FUNC_QM_LABLE_INFORM_MK('免測') ;
  19.   end loop;
  20.   v_end2 := systimestamp;
  21.   dbms_output.put_line('test2:');
  22.   dbms_output.put_line(v_end2-v_start2) ;
  23.   
  24. end ;
trace分析


阿飛
2015/03/19

阅读(3239) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

林順華2015-04-20 17:46:32

赞一个。。。。。。。。。。。。。