对比 PL/SQL profiler 剖析结果

使用PL/SQL PROFILER 剖析PL/SQL代码是快速定位PL/SQL代码段最有效的方法。在上一篇文章使用PL/SQL PROFILER 定位 PL/SQL 瓶颈代码中描述了安装PROFILER,并给出了剖析的示例。本文参照了Tom大师的代码来对比剖析前后的性能并附上其代码。

 

1、用于实施剖析的存储过程

  1. --环境  
  2. sys@USBO> select * from v$version where rownum<2;  
  3.   
  4. BANNER  
  5. ------------------------------------------------------------------------------------------------------------  
  6. Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production  
  7.   
  8. --用于实施剖析的原过程,下面是使用字面量的过程,注意代码中包含了启用与停止profiler  
  9. scott@USBO> create or replace procedure binds  
  10.   2  is  
  11.   3   v_num number;  
  12.   4  begin  
  13.   5  dbms_profiler.start_profiler('binds');  
  14.   6   for i in 1..100000 loop  
  15.   7     v_num := dbms_random.random;  
  16.   8     insert into t1 values (v_num,v_num);  
  17.   9   end loop;  
  18.  10  dbms_profiler.stop_profiler;  
  19.  11  end;  
  20.  12  /  
  21.   
  22. Procedure created.  
  23.   
  24. --用于实施剖析的原过程,下面是使用绑定量的过程,注意代码中包含了启用与停止profiler  
  25. scott@USBO> create or replace procedure literals  
  26.   2  is  
  27.   3   v_num number;  
  28.   4  begin  
  29.   5  dbms_profiler.start_profiler('literals');  
  30.   6   for i in 1..100000 loop  
  31.   7     v_num := dbms_random.random;                 
  32.   8     execute immediate   
  33.   9      'insert into t1 values ('||v_num||','||v_num||')';  
  34.  10   end loop;  
  35.  11  dbms_profiler.stop_profiler;  
  36.  12  end;  
  37.  13  /   
  38.   
  39. Procedure created.  
  40.   
  41. --Author : Leshami  
  42. --Blog   : http://blog.csdn.net/leshami  
  43.   
  44. --清除剖析表中的历史数据(每次剖析对比前执行)  
  45. scott@USBO> delete from plsql_profiler_data;  
  46.   
  47. scott@USBO> delete from plsql_profiler_units;  
  48.   
  49. scott@USBO> delete from plsql_profiler_runs;  
  50.   
  51. --分别执行两个不同的过程  
  52. scott@USBO> exec literals;  
  53.   
  54. scott@USBO> exec binds;  

2、提取剖析对比结果

  1. scott@USBO> @profsum  
  2.   
  3. rows updated.  
  4.   
  5. PL/SQL procedure successfully completed.  
  6.   
  7. =  
  8. =  
  9. ====================  
  10. total time  
  11.   
  12. GRAND_TOTAL  
  13. -----------       
  14.       58.93  
  15.   
  16. =  
  17. =  
  18. ====================  
  19. total time spent on each run  
  20.   
  21.   RUNID RUN_COMMENT      SECS  
  22. ------- ----------- ---------  
  23.       7 literals        53.19  
  24.       8 binds            5.75  
  25.   
  26. =  
  27. =  
  28. ====================  
  29. percentage of time in each module, for each run separately  
  30.   
  31.   RUNID RUN_COMMENT UNIT_OWNER  UNIT_NAME           SECS PERCEN  
  32. ------- ----------- ----------- -------------- --------- ------  
  33.       7 literals    SCOTT       LITERALS           53.19  100.0  
  34.       8 binds       SCOTT       BINDS               5.75  100.0  
  35.   
  36. =  
  37. =  
  38. ====================  
  39. percentage of time in each module, summarized across runs  
  40.   
  41. UNIT_OWNER  UNIT_NAME           SECS PERCENTAG  
  42. ----------- -------------- --------- ---------  
  43. SCOTT       LITERALS           53.19     90.25  
  44. SCOTT       BINDS               5.75      9.75  
  45.   
  46. =  
  47. =  
  48. ====================  
  49. lines taking more than 1% of the total time, each run separate  
  50.   
  51.   RUNID     HSECS     PCT OWNER       UNIT_NAME       LINE# TEXT  
  52. ------- --------- ------- ----------- -------------- ------ ---------------------  
  53.       7   5221.18    88.6 SCOTT       LITERALS            8 execute immediate  
  54.       8    502.97     8.5 SCOTT       BINDS               8 insert into t1 values  
  55.                                                             (v_num,v_num);  
  56.   
  57.       7     73.04     1.2 SCOTT       LITERALS            7 v_num :=  
  58.                                                             dbms_random.random;  
  59.   
  60. =  
  61. =  
  62. ====================  
  63. most popular lines (more than 1%), summarize across all runs  
  64.   
  65.     HSECS     PCT UNIT_OWNER  UNIT_NAME       LINE# TEXT  
  66. --------- ------- ----------- -------------- ------ ---------------------  
  67.   5221.18    88.6 SCOTT       LITERALS            8 execute immediate  
  68.    502.97     8.5 SCOTT       BINDS               8 insert into t1 values  
  69.                                                     (v_num,v_num);  
  70.   
  71.     73.04     1.2 SCOTT       LITERALS            7 v_num :=  
  72.                                                     dbms_random.random;  
  73.   
  74. PL/SQL procedure successfully completed.  
  75.   
  76. =  
  77. =  
  78. ====================  
  79. Number of lines actually executed in different units (by unit_name)  
  80.   
  81. UNIT_OWNER  UNIT_NAME      LINES_EXECUTED LINES_PRESENT     PCT  
  82. ----------- -------------- -------------- ------------- -------  
  83. SCOTT       LITERALS                    4             7    57.1  
  84. SCOTT       BINDS                       4             7    57.1  
  85.   
  86. =  
  87. =  
  88. ====================  
  89. Number of lines actually executed for all units  
  90.   
  91. LINES_EXECUTED  
  92. --------------  
  93.              8  
  94.   
  95. =  
  96. =  
  97. ====================  
  98. total number of lines in all units  
  99.   
  100. LINES_PRESENT  
  101. -------------  
  102.            14  

3、生成剖析结果的脚本

  1. a、脚本profrep.sql  
  2. --在执行剖析前需要先执行该脚本以准备环境(仅首次使用)  
  3. Rem  Copyright (c) Oracle Corporation 1998, 1999. All Rights Reserved.  
  4. Rem  
  5. Rem    NAME  
  6. Rem      profrep.sql  
  7. Rem  
  8. Rem    DESCRIPTION  
  9. Rem      PL/SQL Profiler reporting utilities  
  10. Rem  
  11. Rem    NOTES  
  12. Rem      The reporting procedures expect server output to be set on  
  13. Rem      Some of the rollup functions commit the transaction.  
  14. Rem  
  15.   
  16. -- First create the views used in the reporting package  
  17. --  
  18. create or replace view plsql_profiler_grand_total as  
  19.   select sum(total_time) as grand_total from plsql_profiler_units;  
  20.   
  21. create or replace view plsql_profiler_units_cross_run as  
  22.   select unit_owner, unit_name, unit_type, sum(total_time) as total_time  
  23.     from plsql_profiler_units group by unit_owner, unit_name, unit_type;  
  24.   
  25. create or replace view plsql_profiler_lines_cross_run as  
  26.   select p1.unit_owner as unit_owner, p1.unit_name as unit_name,   
  27.     p1.unit_type as unit_type,   
  28.     p2.line# as line#,  
  29.     sum(p2.total_occur) as total_occur,  
  30.     sum(p2.total_time) as total_time,   
  31.     min(p2.min_time) as min_time,  
  32.     max(p2.max_time) as max_time  
  33.   from plsql_profiler_units p1, plsql_profiler_data p2  
  34.   where p1.runid=p2.runid and p1.unit_number = p2.unit_number  
  35.   group by p1.unit_owner, p1.unit_name, p1.unit_type, p2.line#;  
  36.   
  37. create or replace view plsql_profiler_notexec_lines as  
  38.   select owner, name, type, line, text, total_occur  
  39.   from all_source t1, plsql_profiler_lines_cross_run t2  
  40.   where t2.total_occur = 0 and t2.unit_owner = owner  
  41.     and t2.unit_name = name and t2.unit_type = type and t2.line# = line  
  42.   order by line asc;  
  43.   
  44. create or replace package prof_report_utilities  
  45.   authid current_user is  
  46.   
  47.   -- Routines to roll up profile information from line level to unit level  
  48.   --  
  49.   procedure rollup_unit(run_number IN number, unit IN number);  
  50.   procedure rollup_run(run_number IN number);  
  51.   procedure rollup_all_runs;  
  52.   
  53.   -- Routines to print a report, treating each run separately  
  54.   --  
  55.   procedure print_unit(run_number IN number, unit IN number);  
  56.   procedure print_run(run_number IN number);  
  57.   procedure print_detailed_report;  
  58.   
  59.   -- Routine to print a single report including information from each run  
  60.   --  
  61.   procedure print_summarized_report;  
  62.   
  63.   -- Set size of window for reports  
  64.   procedure set_window_size(window_size IN pls_integer);  
  65.   
  66. end prof_report_utilities;  
  67. /  
  68. show errors;  
  69.   
  70. create or replace  
  71. package body prof_report_utilities is  
  72.   
  73.   -- the reports print 'window' lines of source around lines with profiler  
  74.   -- data, otherwise skipping lines with no data. This is useful when  
  75.   -- viewing data for units with sparse profiler data.  
  76.   --  
  77.   window pls_integer := 10;  
  78.   last_line_printed number := 999999999;  
  79.   
  80.   cursor c2(run number, unit number,  
  81.             owner_name varchar2, unit_name varchar2, unit_type varchar2) is  
  82.     select line, text, total_occur, total_time, min_time, max_time  
  83.       from all_source, plsql_profiler_data  
  84.       where runid (+) = run and unit_number (+) = unit  
  85.         and owner = owner_name and name = unit_name and type = unit_type  
  86.         and plsql_profiler_data.line# (+) = line  
  87.       order by line asc;  
  88.   
  89.   -- c2tab contains the window of lines around any line with interesting  
  90.   -- data.  
  91.   type c2tab_t is table of c2%rowtype index by binary_integer;  
  92.   c2tab    c2tab_t;  
  93.   -- index into the window where previous row was inserted  
  94.   prev_row pls_integer := 0;  
  95.   
  96.   procedure report_exception(which IN varchar2, reraised IN boolean) is  
  97.   begin  
  98.     dbms_output.new_line();  
  99.     dbms_output.new_line();  
  100.     dbms_output.put('======================================');  
  101.     dbms_output.put_line('======================================');  
  102.     dbms_output.put('Exception Number:  ');  
  103.     dbms_output.put(sqlcode);  
  104.     dbms_output.put(' raised in routine ' || which );  
  105.     if (reraised)  
  106.     then  
  107.       dbms_output.put(' (Will be reraised)');  
  108.     end if;  
  109.     dbms_output.new_line();  
  110.     dbms_output.put('======================================');  
  111.     dbms_output.put_line('======================================');  
  112.   end;  
  113.   
  114.   -- compute the total time spent executing this unit - the sum of the  
  115.   -- time spent executing lines in this unit (for this run)  
  116.   --  
  117.   procedure rollup_unit(run_number IN number, unit IN number) is  
  118.   begin  
  119.         dbms_profiler.rollup_unit(run_number, unit);  
  120.   exception  
  121.     when others then  
  122.       report_exception('Rollup_Unit'true);  
  123.       raise;                      
  124.   end rollup_unit;  
  125.   
  126.   -- rollup all units for the given run  
  127.   --  
  128.   procedure rollup_run(run_number IN number) is  
  129.   begin  
  130.         dbms_profiler.rollup_run(run_number);  
  131.   exception  
  132.     when others then  
  133.       report_exception('Rollup_Run'true);  
  134.       raise;                      
  135.   end rollup_run;  
  136.   
  137.   procedure rollup_all_runs is   
  138.     cursor crunid is   
  139.       select runid from plsql_profiler_runs order by runid asc;  
  140.   begin  
  141.     for runidrec in crunid loop  
  142.       dbms_profiler.rollup_run(runidrec.runid);  
  143.     end loop crunid;  
  144.   end rollup_all_runs;  
  145.   
  146.   --  
  147.   -- Reporting functions  
  148.   --  
  149.   
  150.   -- Format and print information on a unit  
  151.   --  
  152.   procedure print_unit_header(run_number IN number, unit IN number) is  
  153.     cursor cuhdr(run_number number, unit number) is  
  154.       select * from plsql_profiler_units   
  155.         where runid = run_number and unit_number = unit;  
  156.     unit_row cuhdr%rowtype;  
  157.   begin  
  158.     -- fetch data for the given unit  
  159.     open cuhdr(run_number, unit);  
  160.     fetch cuhdr into unit_row;  
  161.     close cuhdr;  
  162.   
  163.     -- format and print the data  
  164.     dbms_output.put('Unit #');  
  165.     dbms_output.put(unit_row.unit_number);  
  166.     dbms_output.put(': ');  
  167.     dbms_output.put(unit_row.unit_owner || '.' || unit_row.unit_name);  
  168.     dbms_output.put(' - Total time: ');  
  169.     dbms_output.put(to_char(unit_row.total_time/1000000000, '99999.99'));  
  170.     dbms_output.put_line(' seconds');  
  171.   end print_unit_header;  
  172.   
  173.   -- Format and print information on a run  
  174.   --  
  175.   procedure print_run_header(run_number IN number) is  
  176.     cursor crun(run_number number) is   
  177.       select * from plsql_profiler_runs where runid = run_number;  
  178.     runidrec crun%rowtype;  
  179.   begin  
  180.     open crun(run_number);  
  181.     fetch crun into runidrec;  
  182.     close crun;  
  183.   
  184.     dbms_output.new_line();  
  185.     dbms_output.new_line();  
  186.     dbms_output.put('===========================');  
  187.     dbms_output.put('Results for run #');  
  188.     dbms_output.put(runidrec.runid);  
  189.     dbms_output.put(' made on ');  
  190.     dbms_output.put(to_char(runidrec.run_date, 'DD-MON-YY HH24:MI:SS'));  
  191.     dbms_output.put_line(' =========================');  
  192.     if (runidrec.run_comment is not nullthen  
  193.       dbms_output.put(' (');  
  194.       dbms_output.put(runidrec.run_comment);  
  195.       dbms_output.put(') ');  
  196.     end if;  
  197.     dbms_output.put('Run total time: ');  
  198.     dbms_output.put(to_char(runidrec.run_total_time/1000000000, '99999.99'));  
  199.     dbms_output.put_line(' seconds');  
  200.     if (runidrec.run_system_info is not nullthen  
  201.       dbms_output.put_line(runidrec.run_system_info);  
  202.     end if;  
  203.   end print_run_header;  
  204.        
  205.   --   
  206.   -- Routines for formatting and printing profiler data  
  207.   --  
  208.     
  209.   -- Format and print one line of data and source  
  210.   --  
  211.   procedure print_line(line number, lcount number,  
  212.                        running_total number, source varchar2) is  
  213.     outline    varchar2(200);         -- temp buffer to hold output  
  214.     cline      varchar2(40);          -- number of times this line was executed  
  215.     total_time varchar2(40);          -- total time executing this line  
  216.     ave_time   varchar2(40);          -- average time for this line  
  217.     ave_nano   number;  
  218.   begin  
  219.     outline := to_char(line, '99G999');  
  220.   
  221.     -- format and store away the count and running total  
  222.     if (lcount is not nullthen  
  223.       cline := to_char(lcount, '99G999G999');  
  224.     end if;  
  225.   
  226.     if (running_total is not nullthen  
  227.       total_time := substr(to_char(running_total/1000000000), 1, 9);  
  228.     end if;  
  229.   
  230.     -- compute average time executing this line and stash it away  
  231.     if (lcount > 0) then  
  232.       ave_nano := running_total/lcount;  
  233.       ave_time := substr(to_char(ave_nano/1000000000), 1, 9);  
  234.     end if;  
  235.   
  236.     -- now put together all the data, the source line and output it  
  237.     --  
  238.     outline := outline || ' ' || cline || '   ' ||  
  239.                total_time || '  ' || ave_time || ' ';  
  240.   
  241.     if source is not null then   
  242.       outline := rpad(outline, 55) || substr(source, 1, (length(source) - 1));  
  243.     end if;  
  244.   
  245.     dbms_output.put_line(outline);  
  246.   end print_line;  
  247.   
  248.   -- insert a c2 row into the window  
  249.   --  
  250.   procedure insert_into_window(c2row c2%rowtype) is  
  251.     next_row pls_integer;  
  252.   begin  
  253.     next_row := mod((prev_row + 1), window);  
  254.     c2tab(next_row) := c2row;  
  255.     prev_row := next_row;  
  256.   end insert_into_window;  
  257.   
  258.   -- clear out the window (for reuse later)  
  259.   --  
  260.   procedure clear_window is  
  261.     empty_tab c2tab_t;  
  262.   begin  
  263.     -- throw away table  
  264.     c2tab := empty_tab;  
  265.     prev_row := 0;  
  266.   end clear_window;  
  267.   
  268.   -- print the window and throw it away  
  269.   --  
  270.   procedure print_window(start_separator IN boolean) is  
  271.     next_row  pls_integer;  
  272.     iter      pls_integer;  
  273.     c2row     c2%rowtype;  
  274.     first_line boolean := true;  
  275.     ct        number := c2tab.count;  
  276.   begin  
  277.   
  278.     if (window <= 0) then  
  279.       return;  
  280.     end if;  
  281.   
  282.     -- compute first row  
  283.     next_row := mod((prev_row + 1), window);  
  284.   
  285.     -- Detect the case where the window hasn't wrapped around yet  
  286.     if (not c2tab.exists(next_row)) then  
  287.       next_row := c2tab.next(next_row);  
  288.       if (next_row is NULLthen   
  289.         next_row := c2tab.first;   
  290.       end if;   
  291.     end if;  
  292.   
  293.     for iter in 1..window loop  
  294.       exit when (ct <= 0);  
  295.   
  296.       if (c2tab.exists(next_row)) then  
  297.         c2row := c2tab(next_row);  
  298.         if (first_line and (last_line_printed < c2row.line-1)) then  
  299.           dbms_output.put_line('.');  
  300.           dbms_output.put_line('.');  
  301.           dbms_output.put_line('.');  
  302.         end if;  
  303.         first_line := false;  
  304.         print_line(c2row.line, c2row.total_occur,  
  305.                    c2row.total_time, c2row.text);  
  306.         last_line_printed := c2row.line;  
  307.         ct := ct - 1;  
  308.       end if;  
  309.       next_row := mod((next_row + 1), window);  
  310.     end loop;  
  311.   
  312.     if (not start_separator) then  
  313.       last_line_printed := 999999999;  
  314.     end if;  
  315.     clear_window;  
  316.   end print_window;  
  317.     
  318.   procedure print_unit(run_number number, unit number) is  
  319.     cursor cuhdr(run number, unit number) is  
  320.       select * from plsql_profiler_units  
  321.         where runid = run and unit_number = unit;  
  322.   
  323.     unit_row    cuhdr%rowtype;  
  324.     joined_row  c2%rowtype;  
  325.     lcount      number;  
  326.   
  327.     -- print a trailing window after the last interesting line  
  328.     print_trailing_window boolean := false;  
  329.     trail_count pls_integer := 0;  
  330.   
  331.   begin  
  332.     dbms_profiler.rollup_unit(run_number, unit);  
  333.   
  334.     -- fetch unit name and type information  
  335.     open cuhdr(run_number, unit);  
  336.     fetch cuhdr into unit_row;  
  337.     close cuhdr;  
  338.   
  339.     -- If there was an error previously, cursor "c2" might be open  
  340.     -- Close it, and ignore the error if it already was  
  341.     --  
  342.     begin  
  343.       close c2;  
  344.     exception  
  345.       when others then  
  346.         null;  
  347.     end;  
  348.       
  349.     open c2(run_number, unit,  
  350.             unit_row.unit_owner, unit_row.unit_name, unit_row.unit_type);  
  351.     loop  
  352.       fetch c2 into joined_row;  
  353.       exit when c2%notfound;  
  354.       lcount := joined_row.total_occur;  
  355.   
  356.       -- if there is interesting data at this line, print its prefix window  
  357.       -- and the data itself; else stash away this line c2tab - it may get  
  358.       -- printed as part of another line's window  
  359.       if (lcount is not null and lcount <> 0) then  
  360.         print_window (start_separator => false);  
  361.         print_line(joined_row.line, joined_row.total_occur,  
  362.                    joined_row.total_time, joined_row.text);  
  363.         print_trailing_window := true;  
  364.         trail_count := 0;  
  365.       else  
  366.         insert_into_window(joined_row);  
  367.         -- if we are now accumulating rows after a row with data, increment  
  368.         -- count of rows accumulated since last interesting row. if we have  
  369.         -- accumulated a window full of data, print it out.  
  370.         if (print_trailing_window) then  
  371.           trail_count := trail_count + 1;  
  372.           if (trail_count = window) then  
  373.             print_window(start_separator => true);  
  374.             print_trailing_window := false;  
  375.           end if;  
  376.         end if;  
  377.       end if;  
  378.     end loop;  
  379.     close c2;  
  380.     -- if the window isn't empty, print it out.  
  381.     if (print_trailing_window) then  
  382.       print_window(start_separator => false);  
  383.       print_trailing_window := false;  
  384.     end if;  
  385.     clear_window;  
  386.   exception  
  387.     when others then  
  388.       report_exception('Print_Unit'false);  
  389.   end print_unit;  
  390.   
  391.   procedure print_run(run_number number) is  
  392.     cursor cunits(run_number number) is  
  393.       select unit_number from plsql_profiler_units   
  394.         where runid = run_number order by unit_number asc;  
  395.   begin  
  396.     print_run_header(run_number);  
  397.     dbms_profiler.rollup_run(run_number);  
  398.   
  399.     for unitrec in cunits(run_number) loop  
  400.       print_unit_header(run_number, unitrec.unit_number);  
  401.       print_unit(run_number, unitrec.unit_number);  
  402.     end loop;  
  403.   exception  
  404.     when others then  
  405.       report_exception('Print_Run'false);  
  406.   end print_run;  
  407.   
  408.   procedure print_detailed_report is  
  409.     cursor crunid is   
  410.       select runid from plsql_profiler_runs order by runid asc;  
  411.   begin  
  412.     dbms_output.enable(999999);  
  413.   
  414.     dbms_output.put('=================================');  
  415.     dbms_output.put('trace info');   
  416.     dbms_output.put_line('=================================');  
  417.      
  418.     rollup_all_runs();  
  419.   
  420.     for runidrec in crunid loop  
  421.       print_run(runidrec.runid);  
  422.     end loop crunid;  
  423.   
  424.     dbms_output.new_line;  
  425.     dbms_output.put('======================================');  
  426.     dbms_output.put_line('======================================');  
  427.   exception   
  428.     when others then  
  429.       report_exception('Print_Detailed_Report'false);  
  430.   end print_detailed_report;  
  431.   
  432.   procedure print_summarized_unit(owner_name varchar2,  
  433.                                   unit_name varchar2, unit_type  varchar2) is  
  434.     cursor c3(uowner varchar2, uname varchar2, utype varchar2) is  
  435.       select line, text, total_occur, total_time, min_time, max_time  
  436.         from all_source t1, plsql_profiler_lines_cross_run t2  
  437.         where owner = uowner and name = uname and type = utype  
  438.            and t2.unit_owner (+) = uowner and t2.unit_name (+) = uname  
  439.            and t2.unit_type (+) = utype and t2.line# (+) = line  
  440.         order by line asc;  
  441.   
  442.     datarec c3%rowtype;  
  443.     lcount  number;  
  444.   
  445.     -- print a trailing window after the last interesting line  
  446.     print_trailing_window boolean := false;  
  447.     trail_count pls_integer := 0;  
  448.   begin  
  449.     open c3(owner_name, unit_name, unit_type);  
  450.     loop  
  451.       fetch c3 into datarec;  
  452.       exit when c3%notfound;  
  453.       lcount := datarec.total_occur;  
  454.   
  455.       if (lcount is not null and lcount <> 0) then  
  456.         print_window (start_separator => false);  
  457.         print_line(datarec.line,  
  458.                    datarec.total_occur,  
  459.                    datarec.total_time,  
  460.                    datarec.text);  
  461.         print_trailing_window := true;  
  462.         trail_count := 0;  
  463.       else  
  464.         insert_into_window(datarec);  
  465.         -- if we are now accumulating rows after a row with data, increment  
  466.         -- count of rows accumulated since last interesting row. if we have  
  467.         -- accumulated a window full of data, print it out.  
  468.         if (print_trailing_window) then  
  469.           trail_count := trail_count + 1;  
  470.           if (trail_count = window) then  
  471.             print_window(start_separator => true);  
  472.             print_trailing_window := false;  
  473.           end if;  
  474.         end if;  
  475.       end if;  
  476.     end loop;  
  477.     close c3;  
  478.     -- if the window isn't empty, print it out.  
  479.     if (print_trailing_window) then  
  480.       print_window(start_separator => false);  
  481.       print_trailing_window := false;  
  482.     end if;  
  483.     clear_window;  
  484.   exception  
  485.     when others then  
  486.       report_exception('Print_Summarized_Unit'false);  
  487.   end print_summarized_unit;  
  488.   
  489.   procedure print_summarized_report is  
  490.     cursor cunits is  
  491.       select unit_owner, unit_name, unit_type  
  492.       from plsql_profiler_units_cross_run  
  493.       order by unit_owner, unit_name asc;  
  494.   begin  
  495.     rollup_all_runs();  
  496.     dbms_output.enable(9999999);  
  497.   
  498.     dbms_output.put('================== Profiler report - all runs rolled up');  
  499.     dbms_output.put_line(' ===================');  
  500.   
  501.     for unitrec in cunits loop  
  502.       dbms_output.put('Unit ');  
  503.       dbms_output.put(unitrec.unit_owner);  
  504.       dbms_output.put('.');  
  505.       dbms_output.put(unitrec.unit_name);  
  506.       dbms_output.put_line(':');  
  507.       print_summarized_unit(unitrec.unit_owner,  
  508.                             unitrec.unit_name, unitrec.unit_type);    
  509.     end loop;  
  510.   
  511.     dbms_output.new_line;  
  512.     dbms_output.put('======================================');  
  513.     dbms_output.put_line('======================================');  
  514.   exception   
  515.     when others then  
  516.       report_exception('Print_Summarized_Report'false);  
  517.   end print_summarized_report;  
  518.   
  519.   -- Set size of window for reports  
  520.   procedure set_window_size(window_size IN pls_integer) is  
  521.   begin  
  522.     if (window_size < 0) then  
  523.       window := 999999999;  
  524.     else  
  525.       window := window_size;  
  526.     end if;  
  527.   end set_window_size;  
  528.   
  529. end prof_report_utilities;  
  530. /  
  531. show errors;  
  532.   
  533.   
  534. b、剖析报告脚本profsum.sql  
  535. --file_name: profsum.sql  
  536. set echo off  
  537. set linesize 5000  
  538. set trimspool on  
  539. set serveroutput on  
  540. set termout off  
  541. column owner format a11  
  542. column unit_name format a14  
  543. column text format a21 word_wrapped  
  544. column runid format 999999  
  545. column secs format 99999.99  
  546. column hsecs format 99999.99  
  547. column grand_total format 9999.99  
  548. column run_comment format a11 word_wrapped  
  549. column line# format 99999  
  550. column pct format 9999.9  
  551. column unit_owner format a11  
  552. spool profsum.out  
  553. --Clean out rollup results, and recreate --  
  554. update plsql_profiler_units set total_time = 0;  
  555. execute prof_report_utilities.rollup_all_runs;  
  556. prompt =  
  557. prompt =  
  558. prompt ====================  
  559. prompt total time  
  560. select grand_total/1000000000 as grand_total  
  561. from plsql_profiler_grand_total;  
  562. prompt =  
  563. prompt =  
  564. prompt ====================  
  565. prompt total time spent on each run  
  566. select runid,  
  567.        substr(run_comment,1, 30) as run_comment,  
  568.        run_total_time/1000000000 as secs  
  569. from (select a.runid, sum(a.total_time) run_total_time, b.run_comment  
  570.           from plsql_profiler_units a, plsql_profiler_runs b  
  571.          where a.runid = b.runid group by a.runid, b.run_comment )  
  572. where run_total_time > 0  
  573. order by runid asc;  
  574.   
  575. prompt =  
  576. prompt =  
  577. prompt ====================  
  578. prompt percentage of time in each module, for each run separately  
  579. select p1.runid,  
  580.        substr(p2.run_comment, 1, 20) as run_comment,  
  581.        p1.unit_owner,  
  582.        decode(p1.unit_name, '''<anonymous>',  
  583.                     substr(p1.unit_name,1, 20)) as unit_name,  
  584.        p1.total_time/1000000000 as secs,  
  585.        TO_CHAR(100*p1.total_time/p2.run_total_time, '999.9'as percentage  
  586. from plsql_profiler_units p1,  
  587.        (select a.runid, sum(a.total_time) run_total_time, b.run_comment  
  588.           from plsql_profiler_units a, plsql_profiler_runs b  
  589.          where a.runid = b.runid group by a.runid, b.run_comment ) p2  
  590. where p1.runid=p2.runid  
  591.    and p1.total_time > 0  
  592.    and p2.run_total_time > 0  
  593.    and (p1.total_time/p2.run_total_time) >= .01  
  594. order by p1.runid asc, p1.total_time desc;  
  595. column secs form 99999.99  
  596. prompt =  
  597. prompt =  
  598. prompt ====================  
  599. prompt percentage of time in each module, summarized across runs  
  600. select p1.unit_owner,  
  601.        decode(p1.unit_name, '''<anonymous>', substr(p1.unit_name,1, 25)) as   
  602. unit_name,  
  603.        p1.total_time/1000000000 as secs,  
  604.        TO_CHAR(100*p1.total_time/p2.grand_total, '99999.99'as percentage  
  605. from plsql_profiler_units_cross_run p1,  
  606.        plsql_profiler_grand_total p2  
  607. order by p1.total_time DESC;  
  608.   
  609. prompt =  
  610. prompt =  
  611. prompt ====================  
  612. prompt lines taking more than 1% of the total time, each run separate  
  613. select p1.runid as runid,  
  614.        p1.total_time/10000000 as hsecs,  
  615.         p1.total_time/p4.grand_total*100 as pct,  
  616.        substr(p2.unit_owner, 1, 20) as owner,  
  617.        decode(p2.unit_name, '''<anonymous>', substr(p2.unit_name,1, 20)) as   
  618. unit_name,  
  619.        p1.line#,  
  620.        ( select p3.text  
  621.            from all_source p3  
  622.           where p3.owner = p2.unit_owner and  
  623.                 p3.line = p1.line# and  
  624.                 p3.name=p2.unit_name and  
  625.                 p3.type not in ( 'PACKAGE''TYPE' )) text  
  626. from plsql_profiler_data p1,  
  627.        plsql_profiler_units p2,  
  628.        plsql_profiler_grand_total p4  
  629. where (p1.total_time >= p4.grand_total/100)  
  630.    AND p1.runid = p2.runid  
  631.    and p2.unit_number=p1.unit_number  
  632. order by p1.total_time desc;  
  633. prompt =  
  634. prompt =  
  635. prompt ====================  
  636. prompt most popular lines (more than 1%), summarize across all runs  
  637. select p1.total_time/10000000 as hsecs,  
  638.         p1.total_time/p4.grand_total*100 as pct,  
  639.        substr(p1.unit_owner, 1, 20) as unit_owner,  
  640.        decode(p1.unit_name, '''<anonymous>',  
  641.                  substr(p1.unit_name,1, 20)) as unit_name,  
  642.        p1.line#,  
  643.        ( select p3.text from all_source p3  
  644.           where (p3.line = p1.line#) and  
  645.                 (p3.owner = p1.unit_owner) AND  
  646.                 (p3.name = p1.unit_name) and  
  647.                 (p3.type not in ( 'PACKAGE''TYPE' ) ) ) text  
  648. from plsql_profiler_lines_cross_run p1,  
  649.         plsql_profiler_grand_total p4  
  650. where (p1.total_time >= p4.grand_total/100)  
  651. order by p1.total_time desc;  
  652. execute prof_report_utilities.rollup_all_runs;  
  653. prompt =  
  654. prompt =  
  655. prompt ====================  
  656. prompt Number of lines actually executed in different units (by unit_name)  
  657. select p1.unit_owner,  
  658.        p1.unit_name,  
  659.        count( decode( p1.total_occur, 0, null, 0)) as lines_executed ,  
  660.        count(p1.line#) as lines_present,  
  661.        count( decode( p1.total_occur, 0, null, 0))/count(p1.line#) *100  
  662.                                        as pct  
  663. from plsql_profiler_lines_cross_run p1  
  664. where (p1.unit_type in ( 'PACKAGE BODY''TYPE BODY',  
  665.                           'PROCEDURE''FUNCTION' ) )  
  666. group by p1.unit_owner, p1.unit_name;  
  667.   
  668. prompt =  
  669. prompt =  
  670. prompt ====================  
  671. prompt Number of lines actually executed for all units  
  672. select count(p1.line#) as lines_executed  
  673. from plsql_profiler_lines_cross_run p1  
  674. where (p1.unit_type in ( 'PACKAGE BODY''TYPE BODY',  
  675.                           'PROCEDURE''FUNCTION' ) )  
  676.     AND p1.total_occur > 0;  
  677.   
  678. prompt =  
  679. prompt =  
  680. prompt ====================  
  681. prompt total number of lines in all units  
  682. select count(p1.line#) as lines_present  
  683. from plsql_profiler_lines_cross_run p1  
  684. where (p1.unit_type in ( 'PACKAGE BODY''TYPE BODY',  
  685.                           'PROCEDURE''FUNCTION' ) );  
  686. spool off  
  687. set termout on  
  688. edit profsum.out  
  689. set linesize 131 
Forward from http://blog.csdn.net/leshami/article/details/12110195
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值