Initial setup:
PLSHPROF utility:
Reference
- Oracle 11g Advanced application developers guide
- Oracle 11g PLSQL packages and types reference.
- Www.oracle-base.com
DBMS_UTILITY.GET_DEPENDENCY
type IN VARCHAR2,
schema IN VARCHAR2,
name IN VARCHAR2);
Example usage: set serveroutput on;
BEGIN
dbms_utility.get_dependency('TABLE','HR','EMPLOYEES');
END;
This would list the objects dependent on employees table in HR schema as below in my hr schema: DEPENDENCIES ON HR.EMPLOYEES
------------------------------------------------------------------
*TABLE HR.EMPLOYEES()
* VIEW HR.EMP_DETAILS_VIEW()
* TRIGGER HR.SECURE_EMPLOYEES()
* TRIGGER HR.UPDATE_JOB_HISTORY()
* PROCEDURE HR.ANNUAL_SALARY()
Regards, DBMS_UTILITY.COMPILE_SCHEMA (
schema IN VARCHAR2,
compile_all IN BOOLEAN DEFAULT TRUE,
reuse_settings IN BOOLEAN DEFAULT FALSE);
If compile_all parameter is set as false, this procedure will compile only the invalid objects in the schema. Reuse_settings parameter is a boolean parameter to instruct oracle to reuse session settings for the objects compiled. BEGIN
DBMS_UTILITY.COMPILE_SCHEMA('HR',FALSE,TRUE);
END;
DBMS_PROFILER package, introduced in Oracle8i, provides a means to collect profiling data of plsql program units for performance improvement.
To use dbms_profiler package, we need to create the database tables which will store the profiler data. These tables can be created by running proftab.sql script which will be present in /rdbms/admin folder in the oracle installation folder.
This script creates:
Lets do the initial setup:
1: CONN SYS/PASSWORD AS SYSDBA
2: @/home/oracle/app/oracle/product/11.2.0/dbhome_2/rdbms/admin/proftab.sql
3: CREATE PUBLIC SYNONYM plsql_profiler_runs FOR plsql_profiler_runs;
4: CREATE PUBLIC SYNONYM plsql_profiler_units FOR plsql_profiler_units;
5: CREATE PUBLIC SYNONYM plsql_profiler_data FOR plsql_profiler_data;
6: CREATE PUBLIC SYNONYM plsql_profiler_runnumber FOR plsql_profiler_runnumber;
7: GRANT SELECT ON plsql_profiler_runnumber TO PUBLIC;
8: GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_data TO PUBLIC;
9: GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_units TO PUBLIC;
10: GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_runs TO PUBLIC;
The sets involved in profiling a plsql unit using dbms_profiling is:
An Example:
1: create or replace procedure annual_salary
2: as
3: l_annual_salary NUMBER;
4: begin
5: for i in ( select employee_id, salary from employees)
6: loop
7: l_annual_salary := i.salary * 12;
8: end loop;
9: end annual_salary;
10: /
11: DECLARE
12: l_result BINARY_INTEGER;
13: BEGIN
14: l_result := DBMS_PROFILER.start_profiler(run_comment => 'annual_salary' );
15: annual_salary;
16: l_result := DBMS_PROFILER.stop_profiler;
17: END;
18: /
Run this query
SELECT runid, run_date, run_comment, run_total_time
FROM plsql_profiler_runs
where run_comment = 'annual_salary'
ORDER BY runid;
This gave below output:
To analyze which subprogram or line in the plsql unit profiled took how much time :
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 = 4 ORDER BY u.unit_number, d.line#;
This produces below output:
The lines 6 and 8 has taken maximun time.
Using dbms_profiler, one can tune their plsql units iteratively.
Regards,
Vijay