有一個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的代碼類似如下:
-
SELECT DECODE(VREMARK,
-
'免測', '1',
-
'待測', '2',
-
'測試中', '3',
-
'PASS', '4',
-
'允收', '5',
-
'NG', '6',
-
'MARGINAL', '5',
-
'OK', '4',
-
'空')
-
into v_mk
-
from dual;
-
return v_mk
修改後代碼:
点击(此处)折叠或打开
-
return case VREMARK
-
when '免測' then '1'
-
when '待測' then '2'
-
when '測試中' then '3'
-
when 'PASS' then '4'
-
when '允收' then '5'
-
when 'NG' then '6'
-
when 'MARGINAL' then '5'
-
when 'OK' then '4'
-
else '空'
-
end ;
測試代碼:
-
declare
-
v_start1 timestamp;
-
v_end1 timestamp;
-
v_start2 timestamp;
-
v_end2 timestamp;
-
v_xx varchar2(40) ;
-
begin
-
v_start1 := systimestamp;
-
for r in 1..100000 loop
-
select FUNC_QM_LABLE_INFORM_MK('免測') into v_xx
-
from dual;
-
end loop;
-
v_end1 := systimestamp;
-
dbms_output.put_line('test1:');
-
dbms_output.put_line(v_end1-v_start1) ;
-
-
-
v_start2 := systimestamp;
-
for r in 1..100000 loop
-
v_xx := temp_FUNC_QM_LABLE_INFORM_MK('免測') ;
-
end loop;
-
v_end2 := systimestamp;
-
dbms_output.put_line('test2:');
-
dbms_output.put_line(v_end2-v_start2) ;
-
-
end ;
trace分析
阿飛
2015/03/19
阅读(3297) | 评论(1) | 转发(1) |