www.oradev.com
  Database   Sql   Functions   Packages   Performance   Books   Oracle   Other   About   XML   ORA-messages
  Trace pl/sql performance with DBMS_PROFILER

Performance

Info on performance
dbms_profiler explained
How to use hints
Undocumented hints
How to Trace sessions
Create statistics


  OraDev.com

Trace pl/sql performance with DBMS_PROFILER

Since Oracle 8i we can trace pl/sql like we can trace sql with tkprof. With DBMS_PROFILER you can measure the execution time of a pl/sql program unit.

DBMS_PROFILER gives insight into the following statistics:
- The number of times a piece of pl/sql was executed
- The total time spend on a piece of pl/sql code, including sql statements.
- Minimum and maximum time spend on a piece of pl/sql code
- Which code is executed during profiling.

Example code

This is an example on how to use DBMS_PROFILER:

Prerequisites.

The DBMS_PROFILER package is not automatically created on install of the database. Before you can use it, you should run the following scripts: as sys user run the $ORACLE_HOME/rdbms/admin/profload.sql script. As user that uses the profiler (or as sys with grants) run: $ORACLE_HOME/rdbms/admin/proftab.sql

Procedures

The DBMS_PROFILER package has the following procedures: Start_Profiler: begin data collection Stop_Profiler: stop data collection. Data is not automatically stored when the user disconnects. Flush_Data: flush data collected in user session. Can call at points in a run to get incremental data. Pause_Profiler: pause user data collection Resume_Profiler: resume data collection Get_Version (proc): gets the version of this api. Internal_Version_Check: verify that the DBMS_Profiler version works with this DB version.

Tables

The profiler-information is stored in the following tables: plsql_profiler_runs - information on profiler runs plsql_profiler_units - information on each lu profiled plsql_profiler_data - profiler data for each lu profiled

Run profile session

set serverout on enabled

declare
  run_id number;
begin
  run_id := dbms_profiler.start_profiler(
       to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'));
  ..
  call pl/sql
  ..
  
  /* Clear data from memory and store it in profiler tables.*/
  dbms_profiler.flush_data; 
  dbms_profiler.stop_profiler;
end;

Report on profile session

In Oracle 8i, Oracle supplied a sql ${ORACLE_HOME}/plsql/demo/profrep.sql to report of the profiling results.

In Oracle 10g a sql ${ORACLE_HOME}/plsql/demo/profsum.sql is provided.
-- show procedures
        SELECT substr(u.unit_type,1,30),substr(u.unit_name,1,30)
        , ROUND(d.total_time/10000000,2) total, d.total_occur
        , d.min_time, d.max_time
      FROM plsql_profiler_units u,
           plsql_profiler_data  d
     WHERE u.runid       = &1
       AND u.unit_owner  'SYS'
       AND d.runid       = u.runid
       AND d.unit_number = u.unit_number
       AND ROUND(d.total_time/1000000000,2) > 0.00
     ORDER BY
           d.total_time DESC;
           
           

-- Top 10 slow statements
SELECT * FROM (
select trim(decode(unit_type,'PACKAGE SPEC','PACKAGE',unit_type)||
 ' '||trim(pu.unit_owner)||'.'||trim(pu.unit_name))||
' (line '|| pd.line#||')' object_name
, pd.total_occur
, pd.total_time
, pd.min_time
, pd.max_time
, src.text
, rownum sequencenr
from plsql_profiler_units pu
,    plsql_profiler_data pd
,    all_source src
where pu.unit_owner = user
and pu.runid = &1
and pu.runid=pd.runid 
and pu.unit_number = pd.unit_number
and src.owner = pu.unit_owner 
and src.type = pu.unit_type
and src.name = pu.unit_name 
and src.line = pd.line#
) where sequencenr