在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.
这样就基本达到了我们的目标。我们可以在程序中灵活的配置这项功能,对于提升程序的性能来说也是功不可没。

最新文章

  1. 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
  2. pdf文件的导入导出
  3. img的hover事件闪动
  4. NV OIT algorithm : Depth peeling is a fragment-level depth sorting technique
  5. base64的一个应用情景
  6. Python学习【第十二篇】模块(2)
  7. Python高级应用(3)—— 为你的项目添加验证码
  8. IP地址子网划分
  9. 如何学习Linux性能优化?
  10. LaTeX教程与下载
  11. Script error.深度测试
  12. mysql 备份数据库 mysqldump
  13. 正则表达式,re模块
  14. 【C++】拷贝构造函数和赋值符函数
  15. IDEA安装使用 VisualVM 及VisualVM 远程监视
  16. nodejs 遍历文件夹下所有的图片改名为中文
  17. python魔法函数__dict__和__getattr__的妙用
  18. (转)Java DecimalFormat 用法(数字格式化)
  19. 关于Spring Test 小结
  20. LeetCode OJ:Reverse Bits(旋转bit位)

热门文章

  1. Sqlserver获取所有数据库名,表信息,字段信息,主键信息,以及表结构等。
  2. C基础 读写锁中级剖析
  3. django开发项目实例3--用session是实现简单的登陆、验证登陆和注销功能
  4. 半透明AlphaBlend
  5. WordPress匿名投稿插件:DX-Contribute(WP我要投稿,我要爆料)
  6. 关于在webapi + ef + 视图 + top查询的问题
  7. WCF+Windows2008&&sqlserver2008
  8. thinkphp之自动完成
  9. 笔试之random7生成random10
  10. HDU 5552 Bus Routes(2015合肥现场赛A,计数,分治NTT)