oracle信息統計腳本runstats的創建與驗證


  runstats是《Oracle Database 9i/10g/11g編程藝術:深入數據庫體系結構》作者編寫的一個工具,能對做同一件事情的兩個不同方法進行比較,得出孰優孰劣的結果。我們只需要提供兩個不同的方法,余下的事情都由runstats負責。runstats只負責測量3個要素:

  1. 牆上時鍾或耗時時間:知道牆上時鍾或耗時時間很有用,不過這不是最重要的信息。
  2. 系統統計結果:會並排地i顯示每個方法做某件事(如執行一個解析調用)的次數,並展示出兩者之差
  3. 閂定(latching):這是這個報告的關鍵輸出。

  要使用runstats,需要能訪問幾個V$視圖,並創建一個表來存儲統計結果,還要創建runstats包。為此,需要訪問4個V$表(就是那些神奇的動態性能表):V$STATNAME、V$MYSTAT和V$LATCH和V$TIMER。這四個表其實是別名,真正對象的名稱應為V_$STATNAME、V_$MYSTAT、  V_$LATCH、  V_$TIMER,並且都是在sys賬戶下。如果其他賬戶要訪問這四張表, 需要進行授權。我們需要再scott下進行操作,因此需要將這四張表的select權限授予給scott賬戶。下面進行具體操作。

1在sys賬戶下

1.1將V_$表的查詢權限授權給scott   

View Code
--在sys賬戶下授權視圖查詢權限給scott   
grant SELECT on SYS.v_$statname to "SCOTT" ;
grant SELECT on SYS.v_$mystat to "SCOTT" ;
grant SELECT on SYS.v_$latch to "SCOTT" ;
grant SELECT on SYS.v_$timer to "SCOTT" ;

2在scott賬戶下

2.1查詢V_$表

View Code
--在scott賬戶下測試視圖查詢,發現不能使用別名查詢,只能使用視圖真名
select * from SYS.v_$statname--成功
select * from SYS.v$statname--失敗

2.2創建視圖

View Code
--在scott賬戶下創建視圖
create or replace view stats 
as select 'STAT...' || a.name name, b.value 
      from SYS.v_$statname a, SYS.v_$mystat b 
     where a.statistic# = b.statistic# 
    union all 
    select 'LATCH.' || name,  gets 
      from SYS.v_$latch 
    union all 
    select 'STAT...Elapsed Time', hsecs from SYS.v_$timer; 

2.3創建信息收集表 

View Code
--創建信息收集表 
create global temporary table run_stats 
( runid varchar2(15), 
  name varchar2(80), 
  value int ) 
on commit preserve rows; 

2.4創建runstats包

View Code
--創建包
create or replace package runstats_pkg 
    as 
        procedure rs_start; 
        procedure rs_middle; 
        procedure rs_stop( p_difference_threshold in number default 0 ); 
    end; 
    / 

2.5創建包體

View Code
--創建包體
create or replace package body runstats_pkg 
    as 
    g_start number; 
    g_run1  number; 
    g_run2  number; 
    
    procedure rs_start 
    is 
    begin 
       delete from run_stats; 
       
       insert into run_stats 
       select 'before', stats.* from stats; 
         g_start := dbms_utility.get_cpu_time; 
   end; 
 
   procedure rs_middle 
   is 
   begin 
       g_run1 := (dbms_utility.get_cpu_time-g_start); 
  
       insert into run_stats 
       select 'after 1', stats.* from stats; 
       g_start := dbms_utility.get_cpu_time; 
  
   end; 

   procedure rs_stop(p_difference_threshold in number default 0) 
   is 
   begin 
       g_run2 := (dbms_utility.get_cpu_time-g_start); 
  
       dbms_output.put_line 
       ( 'Run1 ran in ' || g_run1 || ' cpu hsecs' ); 
       dbms_output.put_line 
       ( 'Run2 ran in ' || g_run2 || ' cpu hsecs' ); 
           if ( g_run2 <> 0 ) 
           then 
       dbms_output.put_line 
       ( 'run 1 ran in ' || round(g_run1/g_run2*100,2) || 
         '% of the time' ); 
           end if; 
       dbms_output.put_line( chr(9) ); 
  
       insert into run_stats 
       select 'after 2', stats.* from stats; 
  
       dbms_output.put_line 
       ( rpad( 'Name', 30 ) || lpad( 'Run1', 12 ) || 
         lpad( 'Run2', 12 ) || lpad( 'Diff', 12 ) ); 
  
       for x in 
       ( select rpad( a.name, 30 ) || 
                to_char( b.value-a.value, '999,999,999' ) || 
                to_char( c.value-b.value, '999,999,999' ) || 
                 to_char( ( (c.value-b.value)-(b.value-a.value)),  
                                    '999,999,999' ) data 
           from run_stats a, run_stats b, run_stats c 
          where a.name = b.name 
            and b.name = c.name 
            and a.runid = 'before' 
            and b.runid = 'after 1' 
            and c.runid = 'after 2' 
             
            and abs( (c.value-b.value) - (b.value-a.value) ) 
                  > p_difference_threshold 
          order by abs( (c.value-b.value)-(b.value-a.value)) 
       ) loop 
           dbms_output.put_line( x.data ); 
       end loop; 
  
       dbms_output.put_line( chr(9) ); 
       dbms_output.put_line 
       ( 'Run1 latches total versus runs -- difference and pct' ); 
       dbms_output.put_line 
       ( lpad( 'Run1', 12 ) || lpad( 'Run2', 12 ) || 
         lpad( 'Diff', 12 ) || lpad( 'Pct', 10 ) ); 
  
       for x in 
       ( select to_char( run1, '999,999,999' ) || 
                to_char( run2, '999,999,999' ) || 
                to_char( diff, '999,999,999' ) || 
                to_char( round( run1/decode( run2, 0,  
                             to_number(0), run2) *100,2 ), '99,999.99' ) || '%' data 
           from ( select sum(b.value-a.value) run1, sum(c.value-b.value) run2, 
                         sum( (c.value-b.value)-(b.value-a.value)) diff 
                    from run_stats a, run_stats b, run_stats c 
                   where a.name = b.name 
                    and b.name = c.name 
                     and a.runid = 'before' 
                     and b.runid = 'after 1' 
                     and c.runid = 'after 2' 
                     and a.name like 'LATCH%' 
                   ) 
       ) loop 
           dbms_output.put_line( x.data ); 
       end loop; 
   end; 
  
  end; 
  / 

3.使用runstats

3.1創建表T

View Code
  --創建表
  create table t(x int);

3.2創建存儲過程proc1,使用了一條帶綁定變量的SQL語句

View Code
 --創建存儲過程proc1
  create or replace procedure proc1
  as
  begin
      for i in 1 .. 10000
      loop
          execute immediate
          'insert into t values(:x)' using i;
      end loop;
  end;
  /

3.3創建存儲過程proc2,分別為要插入的每一行構造一條獨立的SQL語句

View Code
 --創建存儲過程proc2
  create or replace procedure proc2
  as
  begin
      for i in 1 .. 10000
      loop
          execute immediate
          'insert into t values('||i||')';
      end loop;
  end;
  /

3.4使dbms_output.put_line 生效

要使用dbms_output.put_line ,則必須在sqlplus中顯式聲明:

 set serverout on

比如:

SQL> set serverout on
SQL> exec dbms_output.put_line('asda');
asda--輸出結果

PL/SQL procedure successfully completed

3.5執行runstats中的方法以及兩個存儲過程

View Code
  exec runstats_pkg.rs_start;
  exec proc1;
  exec runstats_pkg.rs_middle;
  exec proc2;
  exec runstats_pkg.rs_stop(10000);
  /

輸出結果為:

View Code
Run1 ran in 26 cpu hsecs
Run2 ran in 267 cpu hsecs
run 1 ran in 9.74% of the time

Name                                  Run1        Run2        Diff
STAT...parse count (total)              15      10,016      10,001
STAT...session cursor cache hi      10,003           1     -10,002
STAT...consistent gets from ca          39      10,054      10,015
STAT...consistent gets from ca          70      10,087      10,017
STAT...consistent gets                  70      10,087      10,017
STAT...db block gets                10,424      30,369      19,945
STAT...db block gets from cach      10,424      30,369      19,945
STAT...db block gets from cach          65      20,039      19,974
LATCH.cache buffers chains          51,209      71,216      20,007
LATCH.enqueue hash chains               60      20,122      20,062
LATCH.enqueues                          44      20,109      20,065
STAT...session logical reads        10,494      40,456      29,962
STAT...recursive calls              10,131      40,144      30,013
LATCH.kks stats                          3      33,343      33,340
STAT...session uga memory max      123,452      72,940     -50,512
LATCH.shared pool simulator             80      83,641      83,561
STAT...session pga memory           65,536     196,608     131,072
STAT...session uga memory                0     196,392     196,392
LATCH.row cache objects                228     210,126     209,898
LATCH.shared pool                   20,151     339,848     319,697

Run1 latches total versus runs -- difference and pct
Run1        Run2        Diff       Pct
73,042     780,963     707,921      9.35%

PL/SQL 過程已成功完成。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM