调试oracle函数性能(嵌入存储过程)
怀疑某个函数性能不好,那么具体哪里慢?
oracle提供了对存储过程调试的方法
可以将函数封装在里面
conn / as sysdba;
alter session set container=freepdb1;
drop user user1 cascade;
CREATE USER user1 IDENTIFIED BY user1;
grant connect,resource to user1;
grant execute on dbms_lock to user1;
alter user user1 quota unlimited on users;conn user1/user1@localhost/freepdb1:1521
@?/rdbms/admin/proftab.sql
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;CREATE OR REPLACE FUNCTION func1(p_id NUMBER) RETURN numberISv_1 number;BEGINv_1:=p_id+ round(dbms_random.value,2);dbms_lock.sleep(v_1);RETURN v_1;END func1;
/CREATE OR REPLACE FUNCTION func2(p_id NUMBER) RETURN numberISv_1 number;BEGINv_1:=p_id-round(dbms_random.value,2);dbms_lock.sleep(v_1);RETURN v_1;END func2;
/CREATE OR REPLACE FUNCTION func3(p_id NUMBER) RETURN numberISv_1 number;BEGINv_1:=p_id* round(dbms_random.value,2);dbms_lock.sleep(v_1);RETURN v_1;END func3;
/CREATE OR REPLACE procedure sp_profiler_test1
as
v number;
beginfor x in 1..3loopv:=func1(1);dbms_output.put_line('func 1:'||v); v:=func2(1);dbms_output.put_line('func 2:'||v); v:=func3(1);dbms_output.put_line('func 3:'||v); end loop;commit;
end sp_profiler_test1;
/set serverout on
DECLAREv_run_number integer;v_temp1 integer;
BEGIN--启动profilersys.DBMS_PROFILER.start_profiler (run_number => v_run_number);--运行要跟踪的PLSQLsp_profiler_test1; --前一步创建的测试样例存储过程--显示当前跟踪的运行序号(后面查询要用)DBMS_OUTPUT.put_line ('run_number:' || v_run_number);--停止profilersys.DBMS_PROFILER.stop_profiler;
END;
/set linesize 1000
col text format a60
SELECT d.line#, --代码行号s.text, --源代码d.total_time, --总共运行时间(单位10亿分之一秒,即10的-9次方。)d.total_occur, --总共运行次数d.min_time, --最小运行时间d.max_time --最大运行时间FROM plsql_profiler_data d, sys.all_source s, plsql_profiler_units uWHERE d.runid = 1 --运行号(上一步执行相关过程时显示号码)and u.unit_name = 'SP_PROFILER_TEST1' --单元名,即被测试的存储过程名AND u.runid = d.runidAND d.unit_number = u.unit_numberAND d.total_occur <> 0AND s.TYPE(+) = u.unit_typeAND s.owner(+) = u.unit_ownerAND s.name(+) = u.unit_nameAND d.line# = NVL (s.line, d.line#)ORDER BY d.total_time desc, u.unit_number, d.line#;SELECT d.line#, --代码行号s.text, --源代码d.total_time, --总共运行时间(单位10亿分之一秒,即10的-9次方。)d.total_occur, --总共运行次数d.min_time, --最小运行时间d.max_time --最大运行时间FROM plsql_profiler_data d, sys.all_source s, plsql_profiler_units uWHERE d.runid = 1 --运行号(上一步执行相关过程时显示号码)and u.unit_name = 'FUNC3' --单元名,即被测试的存储过程名AND u.runid = d.runidAND d.unit_number = u.unit_numberAND d.total_occur <> 0AND s.TYPE(+) = u.unit_typeAND s.owner(+) = u.unit_ownerAND s.name(+) = u.unit_nameAND d.line# = NVL (s.line, d.line#)ORDER BY d.total_time desc, u.unit_number, d.line#;
看整个存储过程各步骤执行耗时

然后看其中函数FUNC3的耗时

注意表空间读写授权和运行号!
如果没有对users表空间读写权限,可能会遇到下面错误
第 1 行出现错误:
ORA-06528: 执行 PL/SQL profiler 时出错
ORA-06512: 在 "SYS.DBMS_PROFILER", line 132
ORA-06512: 在 line 6
如果查询耗时情况写错了运行号,则可能返回空,你会认为dbms_profiler没用。
