可以使用DBMS_PROFILER进行PL/SQL性能分析,或者进行覆盖性分析。测试如下:
创建存储数据所需表:
?/rdbms/admin/PROFTAB.SQL,在收集信息的用户下执行,创建所需表和存储过程.
或者?/rdbms/admin/PROFLOAD.SQL,在系统用户下执行,创建所需表和存储过程,并将SELECT/INSERT/UPDATE权限授予所有用户,并创建同义词。
权限:
需要有create权限才能收集对象信息的,只有execute权限是不能收集对象信息的;
被分析对象是否需要debug方式编译?不需要,但建议;这样可以获取额外信息.
--测试数据库版本:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
1,分析简单存储过程
1.1创建测试表
drop table p;
create table p
as
select object_id as id from dba_objects where object_id is not null;
alter table p
add constraint pk_p primary key(id);
drop table c;
create table c
as
select object_id as id from dba_objects where object_id is not null and rownum<500;
alter table c
add constraint fk_c_r_p foreign key(id) references p(id) on delete cascade;
create or replace procedure prc_del
is
begin
for x in 1..1000 loop
delete from p where id=x;
end loop;
commit;
end;
/
1.2 开始分析
exec dbms_profiler.start_profiler;
SQL> exec dbms_profiler.start_profiler;
BEGIN dbms_profiler.start_profiler; END;
*
ERROR at line 1:
ORA-06528: Error executing PL/SQL profiler
ORA-06512: at "SYS.DBMS_PROFILER", line 123
ORA-06512: at "SYS.DBMS_PROFILER", line 132
ORA-06512: at line 1
==〉奇怪的错误代码
SQL> @?/rdbms/admin/proftab.sql
exec dbms_profiler.start_profiler;
exec prc_del;
--exec dbms_profiler.flush_data;
exec dbms_profiler.stop_profiler;
1.3分析结果查询
SQL> select runid,run_total_time from mh.plsql_profiler_runs;
RUNID RUN_TOTAL_TIME
---------- --------------
1 1.7716E+11
1 row selected.
SQL> set linesize 200
SQL> r
1 select u.runid, unit_number, unit_type, unit_name
2 from mh.plsql_profiler_runs r, mh.plsql_profiler_units u
3* where r.runid = u.runid
RUNID UNIT_NUMBER UNIT_TYPE UNIT_NAME
---------- ----------- -------------------------------- --------------------------------
1 1 ANONYMOUS BLOCK
1 2 ANONYMOUS BLOCK
1 3 PROCEDURE PRC_DEL
1 4 ANONYMOUS BLOCK
1 5 ANONYMOUS BLOCK
5 rows selected.
col line# for 999
col total_occur for 9999999
col total_time for 99999999999
col min_time for 99999999999
col max_time for 99999999999
col text for a40
select d.line# , d.total_occur , d.total_time ,
d.min_time, d.max_time , s.text
from mh.plsql_profiler_units u, mh.plsql_profiler_data d, all_source s
where u.runid = u.runid
and u.unit_number = d.unit_number
and s.owner = u.unit_owner
and s.name = u.unit_name
and s.TYPE = u.unit_type
and s.line = d.line#;
LINE# TOTAL_OCCUR TOTAL_TIME MIN_TIME MAX_TIME TEXT
----- ----------- ------------ ------------ ------------ ----------------------------------------
1 0 9000 4000 5000 procedure prc_del
4 1003 1001000 1000 4000 for x in 1..1000 loop
5 1002 296954000 60000 18913000 delete from p where id=x;
7 1 221000 221000 221000 commit;
8 1 5000 5000 5000 end;
5 rows selected.
1.4重新创建测试表,获取测试数据如下:
select d.line# , d.total_occur , d.total_time ,
d.min_time, d.max_time , s.text
from mh.plsql_profiler_units u, mh.plsql_profiler_data d, all_source s
where u.runid = u.runid
and u.unit_number = d.unit_number
and s.owner = u.unit_owner
and s.name = u.unit_name
and s.TYPE = u.unit_type
and s.line = d.line#
and u.runid=2
and u.runid=d.runid;
LINE# TOTAL_OCCUR TOTAL_TIME MIN_TIME MAX_TIME TEXT
----- ----------- ------------ ------------ ------------ ----------------------------------------
1 0 19000 19000 19000 procedure prc_del
4 1001 1082000 1000 70000 for x in 1..1000 loop
5 1000 247706000 59000 10843000 delete from p where id=x;
7 1 207000 207000 207000 commit;
8 1 6000 6000 6000 end;
5 rows selected.
1.5 重新创建测试表,子表创建索引,获取测试数据如下:
create index idx_c_id;
select d.line# , d.total_occur , d.total_time ,
d.min_time, d.max_time , s.text
from mh.plsql_profiler_units u, mh.plsql_profiler_data d, all_source s
where u.runid = u.runid
and u.unit_number = d.unit_number
and s.owner = u.unit_owner
and s.name = u.unit_name
and s.TYPE = u.unit_type
and s.line = d.line#
and u.runid=3
and u.runid=d.runid;
LINE# TOTAL_OCCUR TOTAL_TIME MIN_TIME MAX_TIME TEXT
----- ----------- ------------ ------------ ------------ ----------------------------------------
1 0 5000 5000 5000 procedure prc_del
4 1001 989000 1000 16000 for x in 1..1000 loop
5 1000 526245000 58000 283551000 delete from p where id=x;
7 1 207000 207000 207000 commit;
8 1 7000 7000 7000 end;
5 rows selected.
==>外键创建了索引,虽然加快了查询速度,但由于级联删除,导致所耗时间增加。
2,分析有调用关系的存储过程
2.1 创建测试用存储过程
create or replace function prc_a(x int,y int) return int
is
begin
return x+y;
end;
/
create or replace function prc_b(x int,y int) return int
is
begin
return prc_a(x,y);
end;
/
2.2 收集信息
exec dbms_profiler.start_profiler;
set serveroutput on
declare
s int;
begin
for x in 1..100 loop
s := prc_b(x,s);
end loop;
dbms_output.put_line('==>'||s);
end;
/
exec dbms_profiler.stop_profiler;
2.3 查询结果
col unit_name for a15
col line# for 999
col total_occur for 9999999
col total_time for 99999999999
col min_time for 99999999999
col max_time for 99999999999
col text for a40
select u.unit_name,d.line# , d.total_occur , d.total_time ,
d.min_time, d.max_time , s.text
from mh.plsql_profiler_units u, mh.plsql_profiler_data d, all_source s
where u.runid = u.runid
and u.unit_number = d.unit_number
and s.owner = u.unit_owner
and s.name = u.unit_name
and s.TYPE = u.unit_type
and s.line = d.line#
and u.runid=5
and u.runid=d.runid;
UNIT_NAME LINE# TOTAL_OCCUR TOTAL_TIME MIN_TIME MAX_TIME TEXT
--------------- ----- ----------- ------------ ------------ ------------ ----------------------------------------
PRC_B 1 0 107000 1000 3000 function prc_b(x int,y int) return int
PRC_B 4 100 196000 1000 17000 return prc_a(x,y);
PRC_B 5 100 85000 1000 1000 end;
PRC_A 1 0 106000 1000 3000 function prc_a(x int,y int) return int
PRC_A 4 100 88000 1000 1000 return x+y;
PRC_A 5 100 92000 1000 2000 end;
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/18922393/viewspace-755276/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/18922393/viewspace-755276/