DBMS_TRACE. • helps to start and stop plsql tracing in a session ... trunc(sysdate
- v_date ); dbms_output.put_line('Number of days :' || l_num_days); .... Page 21 ...
Profiling PLSQL Vijayaragavan R
DBMS_TRACE • helps to start and stop plsql tracing in a session • Steps involved are: – 1. Start - dbms_trace.set_plsql_trace procedure – 2. running the application code – 3. stop - dbms_trace.clear_plsql_trace procedure
Initial Setup • script to run : tracetab.sql • Path: $ORACLE_HOME/rdbms/admin/ • Tables created: 1. plsql_trace_runs 2. plsql_trace_events
Grants CREATE PUBLIC SYNONYM plsql_trace_runs FOR plsql_trace_runs; CREATE PUBLIC SYNONYM plsql_trace_events FOR plsql_trace_events; CREATE PUBLIC SYNONYM plsql_trace_runnumber FOR plsql_trace_runnumber; GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_trace_runs TO PUBLIC; GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_trace_events TO PUBLIC;
Example Calc_days.sql: create or replace procedure calc_days (v_date in date) is l_num_days number; begin l_num_days := trunc(sysdate- v_date ); dbms_output.put_line('Number of days :' || l_num_days); dbms_output.put_line('Number of months :' || l_num_days *12/365) ; dbms_output.put_line('Number of years : ' || l_num_days /365); end;
Trace Enable alter session set set plsql_debug=TRUE; or alter procedure calc_days compile debug;
Sample Execution begin dbms_trace.set_plsql_trace (dbms_trace.trace_all_lines); dbms_output.put_line ('Trace started'); calc_days(sysdate-10000); dbms_output.put_line('To stop trace'); dbms_trace.clear_plsql_trace; dbms_trace.set_plsql_trace (dbms_trace.trace_enabled_lines); dbms_output.put_line ('Trace started'); calc_days(sysdate-10000); dbms_output.put_line('To stop trace'); dbms_trace.clear_plsql_trace; end;
Trace Analysis Run id: select runid, run_owner , run_date from plsql_trace_runs order by runid; Trace data analysis: SELECT e.runid,e.event_seq,TO_CHAR(e.event_time, 'DD-MON-YYYY HH24:MI:SS') AS event_time,e.event_unit_owner,e.event_unit,e.event_ unit_kind,e.proc_line,e.event_comment FROM plsql_trace_events e WHERE e.runid = 1 ORDER BY e.runid, e.event_seq;
More about Trace Trace Control
TRACE_PAUSE TRACE_RESUME
Tracing Levels: Ø for all calls or only for enabled calls, Ø for all exceptions or only for enabled exceptions Ø for all sqls or only for enabled sql Ø for all lines or only for enabled lines.
DBMS_PROFILER • To collect profiling data of plsql program units for performance improvement • Initial setup – proftab.sql in $ORACLE_HOME/rdbms/ admin – Tables created: • plsql_profiler_data • plsql_profiler_units • plsql_profiler_runs
Grants: CREATE PUBLIC SYNONYM plsql_profiler_runs FOR plsql_profiler_runs; CREATE PUBLIC SYNONYM plsql_profiler_units FOR plsql_profiler_units; CREATE PUBLIC SYNONYM plsql_profiler_data FOR plsql_profiler_data; CREATE PUBLIC SYNONYM plsql_profiler_runnumber FOR plsql_profiler_runnumber; GRANT SELECT ON plsql_profiler_runnumber TO PUBLIC; GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_data TO PUBLIC; GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_units TO PUBLIC; GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_runs TO PUBLIC;
Steps •
Start the profiling session using
dbms_profiler.start_profiling • Run the plsql unit to be profiled • Stop the profiling session using dbms_profiler.stop_profiling
Example: Annual_sal.sql
create or replace procedure annual_salary as l_annual_salary NUMBER; begin for i in ( select employee_id, salary from employees) loop l_annual_salary := i.salary * 12; end loop; end annual_salary;
Sample Execution DECLARE l_result BINARY_INTEGER; BEGIN l_result := DBMS_PROFILER.start_profiler(run_comment => 'annual_salary' ); annual_salary; l_result := DBMS_PROFILER.stop_profiler; END;
Run id SELECT runid, run_date, run_comment, run_total_time FROM plsql_profiler_runs where run_comment = 'annual_salary' ORDER BY runid;
Analyse SELECT u.runid, u.unit_number, u.unit_type, u.unit_owner, u.unit_name, d.line#, d.total_occur, d.total_time, d.min_time, d.max_time FROM plsql_profiler_units u JOIN plsql_profiler_data d ON u.runid = d.runid AND u.unit_number = d.unit_number WHERE u.runid = ORDER BY u.unit_number, d.line#;
DBMS_HPROF • 11g Feature • dynamic execution profile of the plsql program organized by subprogram calls • considers plsql and sql calls separately
Initial setup • • •
dbmshptab.sql $ORACLE_HOME/rdbms/admin tables created: • dbmshp_function_info • dbmshp_parent_child_info • dbmshp_runs
Grants GRANT EXECUTE ON dbms_hprof TO HR; CREATE DIRECTORY PLSQL_HPROF AS '/home/ oracle/plsql_hprof'; GRANT ALL ON DIRECTORY PLSQL_HPROF TO HR;
Example Hprof1.sql
Create or replace procedure hprof1 is Begin Calc_days(sysdate - 1000); End;
Sample Profiling Run: begin dbms_hprof.start_profiling( location => 'PLSQL_HPROF', filename=>'Run1.trc'); hprof1; dbms_hprof.stop_profiling; end;
Raw profiler output P#V PLSHPROF Internal Version 1.0 P#! PL/SQL Timer Started P#C PLSQL."HR"."CALC_DAYS"::7."CALC_DAYS"#c0e1380d4054eb50 #1 P#X 191 P#C PLSQL."SYS"."DBMS_OUTPUT"::11."PUT_LINE"#5892e4d73b579470 #109 P#X 2 P#R P#X 6 P#C PLSQL."SYS"."DBMS_OUTPUT"::11."PUT_LINE"#5892e4d73b579470 #109 P#X 1 P#R P#X 5 P#C PLSQL."SYS"."DBMS_OUTPUT"::11."PUT_LINE"#5892e4d73b579470 #109 P#X 1
Run id SELECT runid, run_timestamp,total_elapsed_time,run_comm ent FROM dbmshp_runs ORDER BY runid;
Analyse declare runid number; begin runid := dbms_hprof.analyze(location=> 'PLSQL_HPROF' , filename=> 'Run1.trc'); dbms_output.put_line(' Run ID = ' ||runid); end;
Symbol id
SELECT symbolid, owner, module, type, funcGon FROM dbmshp_funcGon_info WHERE runid = 1 ORDER BY symbolid;
Heirarchical Info SELECT RPAD(' ', level*2, ' ') || fi.owner || '.' || fi.module AS name, fi.function, pci.subtree_elapsed_time, pci.function_elapsed_time, pci.calls FROM dbmshp_parent_child_info pci JOIN dbmshp_function_info fi ON pci.runid = fi.runid AND pci.childsymid = fi.symbolid WHERE pci.runid = 1 CONNECT BY PRIOR childsymid = parentsymid START WITH pci.parentsymid = 2;
PLSHPROF utility $plshprof -output run1 run1.trc $plshprof –output diff
Thank you !