学习DBMS_PROFILER包诊断存储过程及函数的情能及引申思考

1,学习DBMS_PROFILER包的用法
    1,DBMS_PROFILE包的过程及步骤
          1,以SYSDBA连接数据库
             @ORACLE_HOME/RDBMS/ADMIN/PROFLOAD.SQL ,创建包DBMS_PROFILER
          2,创建PROFILER用户
             CREATE USER PROFILER IDENTIFIED BY SYSTEM ACCOUNT UNLOCK;
             GRANT CONNECT,RESOURCE TO PROFILER;
          3,以SYSDBA角色,创立PROFILER用户对应PLSQL相关表的同义词
             CREATE PUBLIC SYNONYM PLSQL_PROFILER_RUNS FOR PROFILER.PLSQL_PROFILER_RUNS;
             CREATE PUBLIC SYNONYM PLSQL_PROFILER_UNITS FOR PROFILER.PLSQL_PROFILER_UNITS;
             CREATE PUBLIC SYNONYM PLSQL_PROFILER_DATA FOR PROFILER.PLSQL_PROFILER_DATA;
             CREATE PUBLIC SYNONYM PLSQL_PROFILER_RUNNUMBER FOR PROFILER.PLSQL_PROFILER_RUNNUMBER;
          4,连接PROFILER用法,创建PLSQL相关的4个表,然后把
             CONN PROFILER/SYSTEM
             @ORACLE_HOME/RDBMS/ADMIN/PROFTAB.SQL 创建PLSQL相关的表 
          5,以PROFILER用户,授权SELECT,INSERT,DELETE,UPDATE上述表的同义词给PUBLIC,PUBLIC指所有用户
             这样所有用户就可以使用PROFILER功能了
             GRANT SELECT ON PLSQL_PROFILER_RUNNUMBER TO PUBLIC;
             GRANT SELECT,INSERT,UPDATE,DELETE ON PLSQL_PROFILER_RUNS TO PUBLIC;
             GRANT SELECT,INSERT,UPDATE,DELETE ON PLSQL_PROFILER_UNITS TO PUBLIC;
             GRANT SELECT,INSERT,UPDATE,DELETE ON PLSQL_PROFILER_DATA TO PUBLIC;
               
            
            
         
            
    2,DBMS_PROFILER诊断的各个表
          1,关注上述PLSQL表的哪些列
          2,这些PLSQL表之间的关系
          3,这些PLSQL表每个列的含义
          4,DBMS_PROFILER可以诊断除了存储过程之类的匿名块或者查询及DML语句吗,即DBMS_PROFILER包的适用范围
          5,学习DBMS_PROFILER包各个子函数及过程的作用及含义
               问题:1,可能子过程没有清空相关PLSQL表的功能
                         可直接DELETE 这些PLSQL表吗
                     2,有直接查看其用法
    3,DBMS_PROFILER如何进行诊断
        1,查看哪些表的哪些列
        2,如何比对这些性能数据
    4,编写存储过程进行测试
    5,引申思考:
        1,学习一个技术要有递进性即,比如先要掌握其技术的概念,概念之间的联系
           然后进阶学习,直到掌握此概念;进而是应用这些概念进行相关技术的一些操作,从操作层面理解这些概念
        2,制作学习目标及目的时,一定要明确,要有可操作性,如不明确在测试前继续分解,以免测试中迷失自己浪费时间;
           以PLSQL_PROFILER包学习来说,目标要具体,即要掌握PLSQL_PROFILER_DATA,RUNS_UNITS表的含义及每个列的作用;
           到哪儿去获了这些信息,一般是官方手册或者上网查资料
        3,往往一个技术要涉及到多个问题,在制定目标时,每进行一个小目标时,就进行专题分析,不要图快,最终什么也没学好;
           只有每个小目标学好,最终可以掌握这个技术的使用;比如PLSQL表的关系,PLSQL表的重要列的含义
          
          
----------------------------------------
  
SQL> conn scott/system
已连接。
SQL> exec dbms_profiler.start_profiler('test profiler');
PL/SQL 过程已成功完成。

SQL> create table t_profiler(a int,b int);
表已创建。
SQL> insert into t_profiler(a,b) values(1,1);
已创建 1 行。
SQL> insert into t_profiler(a,b) values(12,12);
已创建 1 行。
SQL> commit;
提交完成。
SQL> exec dbms_profiler.stop_profiler;
PL/SQL 过程已成功完成。
SQL> desc plsql_profiler_runs;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 RUNID                                     NOT NULL NUMBER
 RELATED_RUN                                        NUMBER
 RUN_OWNER                                          VARCHAR2(32)
 RUN_DATE                                           DATE
 RUN_COMMENT                                        VARCHAR2(2047)
 RUN_TOTAL_TIME                                     NUMBER
 RUN_SYSTEM_INFO                                    VARCHAR2(2047)
 RUN_COMMENT1                                       VARCHAR2(2047)
 SPARE1                                             VARCHAR2(256)
--RUN_TOTAL_TIME是以纳秒计的运行时间
SQL> select runid,run_owner,to_char(run_date,'yyyymmdd hh24:mi:ss'),run_comment,
run_total_time,run_system_info from plsql_profiler_runs;
     RUNID RUN_OWNER                        TO_CHAR(RUN_DATE,
---------- -------------------------------- -----------------
RUN_COMMENT
--------------------
RUN_TOTAL_TIME
--------------
RUN_SYSTEM_INFO
----------------------
         2 SCOTT                            20120911 10:08:10
test profiler
    7.5532E+10

---从如下分析看,DBMS_PROFILER包不能分析DML和SELECT单个语句的执行性能
SQL> select line#||' :'||text from all_source where wner='PROFILER';
select line#||' :'||text from all_source where wner='PROFILER'
       *
第 1 行出现错误:
ORA-00904: "LINE#": 标识符无效

SQL> select line||' :'||text from all_source where wner='PROFILER';
未选定行
SQL> show user
USER 为 "SCOTT"
SQL> select line||' :'||text from all_source where wner='SCOTT';
未选定行
--根据PLSQL_PROFILER_RUNS的RUNID及RUN_COMMENT从下2表获取存储过程运行的相关时间及运行次数信息
 1  select u.runid,u.unit_name,u.unit_type,d.line#,d.total_occur,d.total_time,d
max_time,d.min_time
 2  from plsql_profiler_units u join
 3  plsql_profiler_data d
 4  on u.runid=d.runid and u.unit_number=d.unit_number
 5* where u.runid=4 order by u.unit_name,d.line#

UNID UNIT_NAME    UNIT_TYPE  LINE# TOTAL_OCCUR TOTAL_TIME   MAX_TIME   MIN_TIME
---- ------------ ---------- ----- ----------- ---------- ---------- ----------
   4   ANONYMOUS      1           1       1152       1152       1152
                  BLOCK
   4   ANONYMOUS      1           2     116605     109359       1653
                  BLOCK
   4   ANONYMOUS      1           3      79497      71735       1763
                  BLOCK
   4   ANONYMOUS      1           2      95798      89464       2219
                  BLOCK

UNID UNIT_NAME    UNIT_TYPE  LINE# TOTAL_OCCUR TOTAL_TIME   MAX_TIME   MIN_TIME
---- ------------ ---------- ----- ----------- ---------- ---------- ----------

   4   ANONYMOUS      1           2   32016467   31893888       8288
                  BLOCK
   4 PROC_ZXY     PROCEDURE      1           0       5236       5236       5236
   4 PROC_ZXY     PROCEDURE      5           1   16421901   16421901   16421901
   4 PROC_ZXY     PROCEDURE      6           1   16420438   16420438   16420438
   4 PROC_ZXY     PROCEDURE      7           1       3167       3167       3167

已选择9行。
上述测试问题:
   1,为何运行存储过程会出现UNIT_TYPE的ANONYMOUS BLOCK,它与PROCEDURE有何关系
          1,测试下函数,会有此情况吗
          2,其它情况分析
          3,经分析,运行FUNCTION函数时了, 也会产生2个匿名块的RUNID而且LINE#全是1,
             这种类型的数据不能在ALL_SOURCE中查出,因为没有与之类型匹配
   2,运行一个存储过程为何会出现2个RUNID,要加深对于PLSQL_PROFILER_RUNS表的各个列理解
          1,存储过程及函数分别测试,是否会出现2个RUNID
            
     
 1* select runid,to_char(run_date,'yyyymmdd hh24:mi:ss'),run_comment from plsql
profiler_runs
    RUNID TO_CHAR(RUN_DATE, RUN_COMMENT
--------- ----------------- ------------------------------
        2 20120911 10:08:10 test profiler
        3 20120911 11:09:26 test procedure
        4 20120911 11:11:57 test procedure
        5 20120911 14:12:14 other_func_zxy --表中存储了运行一次函数FUNC_ZXY的RUNID为5的记录了
 
--再次运行FUNC_ZXY函数,看是否另存储一条记录在上述的表中
QL> exec dbms_profiler.start_profiler('other_fun_zxy_2');
L/SQL 过程已成功完成。
QL> select func_zxy from dual;
UNC_ZXY
-------------
1-9月 -12
QL> exec dbms_profiler.stop_profiler;
L/SQL 过程已成功完成。
QL> select runid,to_char(run_date,'yyyymmdd hh24:mi:ss'),run_comment from plsql
profiler_runs;
    RUNID TO_CHAR(RUN_DATE, RUN_COMMENT
--------- ----------------- ------------------------------
        2 20120911 10:08:10 test profiler
        3 20120911 11:09:26 test procedure
        4 20120911 11:11:57 test procedure
        5 20120911 14:12:14 other_func_zxy
        6 20120911 14:27:41 other_fun_zxy_2
小结:同一个存储过程或函数多次运行会存储多条记录,是以RUNID区别,以RUN_COMMENT及RUN_DATE来区别的
 

目标:学习表plsql_profiler_units
   1,了解此表结构
          此表与PLSQL_PROFILER_RUNS相对应关联,即RUNID来关联,一条PLSQL_PROFILER_RUNS对应一条PLSQL_PROFILER_UNITS记录
          另发现此表也存储关于匿名块的记录,即存储过程运行多次,在此表会出现多次记录,即多个RUNID,但每次的UNIT_NAME和UNIT_NUMBER是一样的
   2,测试多次运行函数此表数据的变化规则,更好理解此表的结构含义
SQL> select unit_name,unit_number from plsql_profiler_units
UNIT_NAME                        UNIT_NUMBER
-------------------------------- -----------
                                1
                                2
                                3
                                4
                                1
                                2
                                1
                                2
                                3
PROC_ZXY                                   4
                                5
UNIT_NAME                        UNIT_NUMBER
-------------------------------- -----------
                                6
                                1
FUNC_ZXY                                   2
                                3
                                1
FUNC_ZXY                                   2
                                3
已选择18行。
 
目标:学习PLSQL_PROFILER_DATA表
SQL> select unit_name,unit_number from plsql_profiler_units where runid=5;
UNIT_NAME                        UNIT_NUMBER
-------------------------------- -----------
                                1
FUNC_ZXY                                   2 --确定运行过函数FUNC_ZXY的UNIT_NUMBER,用它和RUNID来唯一确定PLSQL_PROFILER_DATA关于运行此函数的相关数据
                                             --如果不加UNIT_NUMBER,会有匿名块的数据
                                3
SQL> select unit_name,unit_number from plsql_profiler_units where runid=5 and un
it_number=2;
UNIT_NAME                        UNIT_NUMBER
-------------------------------- -----------
FUNC_ZXY                                   2
--
SQL> select runid,unit_number,line#,total_occur,total_time from plsql_profiler_d
ata where runid=5 and unit_number=2;
     RUNID UNIT_NUMBER      LINE# TOTAL_OCCUR TOTAL_TIME
---------- ----------- ---------- ----------- ----------
         5           2          1           0       7606
         5           2          6           1     254246
         5           2          7           1       1698
         5           2          8           1       6594
小结:
      1,PLSQL_PROFILER_DATA与PLSQL_PROFILER_UNITS是1:N的关系,DATA表是运行过函数和过程的细节数据
      2,通过关联ALL_SOURCE可以定位每行函数或存储过程的代码,进一步分析]
 
 
 
总结:
     1,把复杂的问题分解化,而且分解要具体化,要有可操作性
           这样才能通过不同角度理解问题,进而掌握技术应用
     2,   学习不能急,每碰到问题,标题每步碰到什么问题,不能饶过
           因为可能往往这个问题就和你下面要学习的某些知识点有关系
     3,边作测边整理文档,不要测试完了再整理
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
       
请使用浏览器的分享功能分享到微信等