通過pl/sql計算程序的運行時間
在sqlplus中運行sql語句或者pl/sql的時候如果需要統計運行的時間,只需要開啟set timing on選項即可。
SQL> set timing on
SQL>
SQL> select count(*)from cat;
COUNT(*)
----------
408
Elapsed: 00:00:00.15
如果在運行pl/sql的時候如果需要計算程序運行的時間。使用set timing on就顯得力不從心了。這個時候可以考慮使用dbms_utility.get_time來得到一個時間戳,然後在程序運行之後再得到一個時間戳,兩者想減就是程序的運行時間。
set serveroutput on
declare
l_start_time PLS_INTEGER;
begin
l_start_time := dbms_utility.get_time();
dbms_output.put_line(‘this is a test‘);
dbms_lock.sleep(2); --這裏我們嘗試使pl/sql塊停滯2秒鐘
dbms_output.put_line(‘Elapsed time :‘||(dbms_utility.get_time-l_start_time)/100);
end;
/
程序運行的結果如下。
this is a test
Elapsed time :2.01
PL/SQL procedure successfully completed.
但是如果這樣計算,可能會出現負數的情況。在pl/sql程序設計這本書中,作者給出的解釋是,dbms_utility_get_time得到的數字式從某一個時間點以來所經過的總的毫秒數。而這個數字很大,很可能越界,越界的時候就會從0開始重新開始計數。如果這樣計算的話,很可能計算出來的結果就是一個負數了。
我們可以使用如下的pl/sql來做一個改進。
set serveroutput on
declare
c_time_gap number:=power(2,32);
l_start_time PLS_INTEGER;
begin
l_start_time := dbms_utility.get_time();
dbms_output.put_line(‘this is a test‘);
dbms_lock.sleep(2);
dbms_output.put_line(‘Elapsed time :‘||mod(dbms_utility.get_time-l_start_time+c_time_gap,c_time_gap)/100);
end;
/
運行結果如下:
this is a test
Elapsed time :2
PL/SQL procedure successfully completed.
如果我們在程序中嵌入過多的代碼去維護start_time,end_time必然會造成程序的依賴性,如果能夠把計算時間的功能獨立出來就好了。這樣程序的運行不必完全依賴於時間計算,可以靈活的添加和刪除。
這種實現在spring的AOP是根據動態代理來實現的,在pl/sql中我們可以使用package來實現。
我們的期望結果就是
begin
pro_timing.start_timer; --程序計算起始時間
dbms_output.put_line(‘this is a test‘); --程序業務邏輯
dbms_lock.sleep(2); --程序業務邏輯
pro_timing.show_elapsed(‘test program‘); --程序計算終止時間
end;
/
我們可以使用如下的package來實現。
create or replace package pro_timing
authid current_user
is
procedure start_timer;
procedure show_elapsed(program_name in varchar2);
end;
/
create or replace package body pro_timing
is
c_time_gap number:=power(2,32);
l_start_time PLS_INTEGER;
procedure start_timer
is
begin
l_start_time := dbms_utility.get_time();
end;
procedure show_elapsed(program_name in varchar2)
as
l_end_time varchar2(100);
begin
l_end_time:=mod(dbms_utility.get_time-l_start_time+c_time_gap,c_time_gap)/100;
dbms_output.put_line(program_name||‘ has elapsed time ‘||l_end_time||‘ s.‘);
end;
end;
/
我們來嘗試運行如下的pl/sql塊。
begin
pro_timing.start_timer;
dbms_output.put_line(‘this is a test‘);
dbms_lock.sleep(2);
pro_timing.show_elapsed(‘test program‘);
end;
/
運行結果如下:
this is a test
test program has elapsed time 2 s.
PL/SQL procedure successfully completed.
這樣就基本達到了我們的目標。我們可以在程序中靈活的配置這項功能,對於提升程序的性能來說也是功不可沒。
通過pl/sql計算程序的運行時間