【ORACLE】Runstatus_pkg 性能比较工具脚本及使用

来源:互联网 发布:淘宝上分期付款买手机 编辑:程序博客网 时间:2024/05/24 07:11

Runstats_pkg是Thomas Kyte大师开发的一个工具,能对处理同一件事务的两个不同实现方法进行比较,得出孰优孰劣的结果。
该方法测量以下3个要素:
1、比较两个语句执行的墙上时钟时间(wall clock time);
2、系统统计数据;
3、闩定(latching)使用报告(关键输出)。
闩(latch)作为一种轻量级的锁(lock),同样不支持并发操作,在应用中应尽量少用,以提升性能。

一、对用户授权
使用Runstatus的过程需要调用几个系统视图,必须预先对这些视图进行授权,这些视图包括v_statname、v_mystat、v_latch、v_timer。
以授权用户scott为例:

grant create view to scott;     grant select on sys.v_$timer to scott;     grant select on v_$mystat to scott;     grant select on sys.v_$statname to scott;     grant select on sys.v_$latch to scott;     grant select any table to scott;

二、安装runstats_pkg包脚本

set echo ondrop table run_stats;create global temporary table run_stats( runid varchar2(15),  name varchar2(80),  value int )on commit preserve rows;create or replace view statsas select 'STAT...' || a.name name, b.value      from v$statname a, v$mystat b     where a.statistic# = b.statistic#    union all    select 'LATCH.' || name,  gets      from v$latch    union all    select 'STAT...Elapsed Time', hsecs from v$timer;delete from run_stats;commit;create or replace package runstats_pkgas    procedure rs_start;    procedure rs_middle;    procedure rs_stop( p_difference_threshold in number default 0 );end;/create or replace package body runstats_pkgasg_start number;g_run1  number;g_run2  number;procedure rs_startisbegin    delete from run_stats;    insert into run_stats    select 'before', stats.* from stats;    g_start := dbms_utility.get_time;end;procedure rs_middleisbegin    g_run1 := (dbms_utility.get_time-g_start);    insert into run_stats    select 'after 1', stats.* from stats;    g_start := dbms_utility.get_time;end;procedure rs_stop(p_difference_threshold in number default 0)isbegin    g_run2 := (dbms_utility.get_time-g_start);    dbms_output.put_line    ( 'Run1 ran in ' || g_run1 || ' hsecs' );    dbms_output.put_line    ( 'Run2 ran in ' || g_run2 || ' hsecs' );    dbms_output.put_line    ( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||      '% of the time' );    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 (c.value-a.value) > 0         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/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;/

三、调用方法
1、调用runStats_pkg.rs_start
exec runStats_pkg.rs_start;
使用第一种方法执行SQL语句

2、调用runStats_pkg.rs_middle
exec runStats_pkg.rs_middle;
使用第二种方法执行SQL语句

3、最后生成报告
exec runStats_pkg.rs_stop;