Oracle使用profiler来测试PL/SQL的性能

Oracle使用profiler来测试PL/SQL的性能

在Oracle中我们可以很容易的获取sql语句的执行计划,根据执行计划我们就可以基本上判断出该SQL语句的执行效率,那么我们怎么在Oracle中测试PL/SQL代码的执行效率呢?例如我们有一个存储过程testplsql,我想看一下这个存储过程在那一步比较耗时?这个时候我们就可以使用profiler来进行获取这个存储过程的执行效率,废话不多说,我们直接来看看profiler的使用。

1.安装profiler

先在sys用户执行$ORACLE_HOME/rdbms/admin/profload.sql这个脚本,再在需要测试的PL/SQL代码的用户下执行$ORACLE_HOME/rdbms/admin/proftab.sql
例如,在demo用户下有一个存储过程testplsql,我们现在想测试testplsql的运行效率,按照上面的步骤,先在sys用户下执行$ORACLE_HOME/rdbms/admin/profload.sql,再在demo用户下执行$ORACLE_HOME/rdbms/admin/proftab.sql

SQL> show user;
USER is "SYS"
SQL> @?/rdbms/admin/proftab.sql
drop table plsql_profiler_data cascade constraints
           *
ERROR at line 1:
ORA-00942: table or view does not exist
drop table plsql_profiler_units cascade constraints
           *
ERROR at line 1:
ORA-00942: table or view does not exist
drop table plsql_profiler_runs cascade constraints
           *
ERROR at line 1:
ORA-00942: table or view does not exist
drop sequence plsql_profiler_runnumber
              *
ERROR at line 1:
ORA-02289: sequence does not exist
Table created.
Comment created.
Table created.
Comment created.
Table created.
Comment created.
Sequence created.


SQL> conn demo/demo
Connected.
SQL> show user;
USER is "DEMO"
SQL> @?/rdbms/admin/proftab.sql
drop table plsql_profiler_data cascade constraints
           *
ERROR at line 1:
ORA-00942: table or view does not exist
drop table plsql_profiler_units cascade constraints
           *
ERROR at line 1:
ORA-00942: table or view does not exist
drop table plsql_profiler_runs cascade constraints
           *
ERROR at line 1:
ORA-00942: table or view does not exist
drop sequence plsql_profiler_runnumber
              *
ERROR at line 1:
ORA-02289: sequence does not exist
Table created.
Comment created.
Table created.
Comment created.
Table created.
Comment created.
Sequence created.

2.运行测试代码

在需要测试的存储过程的用户下执行下面的代码:
declare
  err number;
 begin
   err :=dbms_profiler.start_profiler(to_char(sysdate,'dd_Mon_YYYY hh:mi:ss'));
   --此处请输入要测试的存储过程名
   err :=dbms_profiler.stop_profiler;
 end;
例如,我们要在测试demo用户下testplsql这个存储过程,则我们在demo用户下执行下面的代码:
declare
  err number;
 begin
   err :=dbms_profiler.start_profiler(to_char(sysdate,'dd_Mon_YYYY hh:mi:ss'));
   testplsql;
   err :=dbms_profiler.stop_profiler;
 end;

其中testplsql的代码为:
create or replace procedure testplsql is
anumber number;
ainteger integer;
anumber_10 number(10);
apls_integer pls_integer;
abinary binary_integer;
err number;
begin
  anumber :=0;
  loop
    anumber :=anumber+1;
    ainteger :=ainteger+1;
    anumber_10 :=anumber_10+1;
    apls_integer :=apls_integer+1;
    abinary :=abinary+1;
    exit when anumber>1500;
   end loop;
end;

3.获取运行id

完成上面的第二步后,我们在需要测试的存储过程用户下执行下面的sql语句,来查询出运行的id:
col run_commnet format a40 truncate;
select runid,run_date,run_comment from plsql_profiler_runs order by runid;
例如,接着我们在demo用户下执行上面这个语句:
SQL> select runid,run_date,run_comment from plsql_profiler_runs order by runid;

     RUNID RUN_DATE  RUN_COMMENT
---------- --------- ----------------------------------------
1 18-FEB-16 18_Feb_2016 05:17:09
2 19-FEB-16 19_Feb_2016 10:00:39
3 19-FEB-16 19_Feb_2016 10:02:18
根据run_comment可以判断出,我们这次测试的runid为3

4.获取测试结果

在3步中我们获取了runid后,这时我们就可以在需要的测试的存储过程用户下直接运行下面的sql语句来获取测试结果:
col unit_name format a15 truncate;
col occured format 999999;
col line# format 99999;
col tot_time format 999.999999;


select p.unit_name,
       p.occured,
       p.tot_time,
       p.line# line,
       substr(s.text, 1, 75) text
  from (select u.unit_name,
               d.total_occur occured,
               (d.total_time / 1000000000) tot_time,
               d.line#
          from plsql_profiler_units u, plsql_profiler_data d
         where d.runid = u.runid
           and d.unit_number = u.unit_number
           and d.total_occur > 0
           and u.runid = &run_id) p,
       user_source s
 where p.unit_name = s.name(+)
   and p.line# = s.line(+)
 order by p.unit_name, p.line#;
例如, 我们在demo用户下运行上面的语句,则会得到下面的结果:
Oracle使用profiler来测试PL/SQL的性能_第1张图片
从结果中我们可以很清楚的看出存储过程每一步的耗时,以及发生的次数!

至此,使用profiler测试存储过程的效率已经完成!

你可能感兴趣的:(oracle)