tom的runstats性能比较工具 测试实验

tomrunstats性能比较工具 测试实验

runStats是Tom大师写的一个脚本,用于比较两个语句的时间,统计数据和栓锁使用情况。

 

下面使用绑定变量和不使用绑定变量查询做对比,查看时间、统计数据和拴锁使用情况。

 

1.先看runstats脚本内容

----1.1创建使用视图

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;

 

----1.2视图创建后,创建一个小表来收集统计结果

create global temporary table run_stats

( runid varchar2(15),

  name varchar2(80),

  value int )

on commit preserve rows;

 

----1.3创建runstats包。包含3个简单的API调用

create or replace package runstats_pkg

as

    procedure rs_start;

    procedure rs_middle;

    procedure rs_stop( p_difference_threshold in number default 0 );

end;

/

---- 参数p_difference_threshold用于控制最后打印的数据量

 

----1.4分析包体中的过程。包前面是一些全局变量,这些全局变量用于记录每次运行的耗用时间

create or replace package body runstats_pkg

as

 

g_start number;

g_run1 number;

g_run2 number;

----下面是rs_start例程

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;

----下面是rs_middle例程

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;

----这个包是最后一个过程,是rs_stop例程

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 (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/decode( run2, 0, to_number(null), 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;

/

----下面就可以使用runstats了

 

2.使用注意

要使用runstats,需要能访问几个v$视图,还要创建runstats包。

授权中使用的对象名应该以v_$而不是v$开头。这些v$名只是同义词,他们分别指向名字以v_$开头的底层视图。

需要授予访问权限的v$视图为:v$statname、v$mystat、v$latch、v$timer

 

3.实验开始,创建runstats

sys@ORCL>create or replace view stats

  2  as select 'STAT...' || a.name name, b.value

  3        from sys.v_$statname a, sys.v_$mystat b

  4       where a.statistic# = b.statistic#

  5      union all

  6      select 'LATCH.' || name, gets

  7        from sys.v_$latch

  8      union all

  9      select 'STAT...Elapsed Time', hsecs from sys.v_$timer;

 

View created.

 

sys@ORCL>create global temporary table run_stats

  2  ( runid varchar2(15),

  3    name varchar2(80),

  4    value int )

  5  on commit preserve rows;

 

Table created.

 

sys@ORCL>create or replace package runstats_pkg

  2  as

  3      procedure rs_start;

  4      procedure rs_middle;

  5      procedure rs_stop( p_difference_threshold in number default 0 );

  6  end;

  7  /

 

Package created.

 

sys@ORCL>create or replace package body runstats_pkg

  2  as

  3 

  4  g_start number;

  5  g_run1 number;

  6  g_run2 number;

  7  procedure rs_start

  8  is

  9  begin

 10      delete from run_stats;

 11 

 12      insert into run_stats

 13      select 'before', stats.* from stats;

 14         

 15      g_start := dbms_utility.get_cpu_time;

 16  end;

procedure rs_middle

is

 18   19  begin

 20      g_run1 := (dbms_utility.get_cpu_time-g_start);

 21  

 22      insert into run_stats

 23      select 'after 1', stats.* from stats;

 24      g_start := dbms_utility.get_cpu_time;

 25 

 26  end;

 27  procedure rs_stop(p_difference_threshold in number default 0)

 28  is

 29  begin

 30      g_run2 := (dbms_utility.get_cpu_time-g_start);

 31 

 32      dbms_output.put_line

 33      ( 'Run1 ran in ' || g_run1 || ' cpu hsecs' );

 34      dbms_output.put_line

 35      ( 'Run2 ran in ' || g_run2 || ' cpu hsecs' );

 36          if ( g_run2 <> 0 )

 37          then

 38      dbms_output.put_line

 39      ( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||

 40        '% of the time' );

 41          end if;

 42      dbms_output.put_line( chr(9) );

 43 

 44      insert into run_stats

 45      select 'after 2', stats.* from stats;

 46 

 47      dbms_output.put_line

 48      ( rpad( 'Name', 30 ) || lpad( 'Run1', 12 ) ||

 49        lpad( 'Run2', 12 ) || lpad( 'Diff', 12 ) );

 50 

 51      for x in

 52      ( select rpad( a.name, 30 ) ||

 53               to_char( b.value-a.value, '999,999,999' ) ||

 54               to_char( c.value-b.value, '999,999,999' ) ||

 55               to_char( ( (c.value-b.value)-(b.value-a.value)), '999,999,999' ) data

 56          from run_stats a, run_stats b, run_stats c

 57         where a.name = b.name

 58           and b.name = c.name

 59           and a.runid = 'before'

 60           and b.runid = 'after 1'

 61           and c.runid = 'after 2'

 62           -- and (c.value-a.value) > 0

 63           and abs( (c.value-b.value) - (b.value-a.value) )

 64                 > p_difference_threshold

 65         order by abs( (c.value-b.value)-(b.value-a.value))

 66      ) loop

 67          dbms_output.put_line( x.data );

 68      end loop;

 69 

 70      dbms_output.put_line( chr(9) );

 71      dbms_output.put_line

 72      ( 'Run1 latches total versus runs -- difference and pct' );

 73      dbms_output.put_line

 74      ( lpad( 'Run1', 12 ) || lpad( 'Run2', 12 ) ||

 75        lpad( 'Diff', 12 ) || lpad( 'Pct', 10 ) );

 76 

 77      for x in

 78      ( select to_char( run1, '999,999,999' ) ||

 79               to_char( run2, '999,999,999' ) ||

 80               to_char( diff, '999,999,999' ) ||

 81               to_char( round( run1/decode( run2, 0, to_number(null), run2) *100,2 ), '99,999.99' ) || '%' data

 82          from ( select sum(b.value-a.value) run1, sum(c.value-b.value) run2,

 83                        sum( (c.value-b.value)-(b.value-a.value)) diff

 84                   from run_stats a, run_stats b, run_stats c

 85                  where a.name = b.name

 86                    and b.name = c.name

 87                    and a.runid = 'before'

 88                    and b.runid = 'after 1'

 89                    and c.runid = 'after 2'

 90                    and a.name like 'LATCH%'

 91                  )

 92      ) loop

 93          dbms_output.put_line( x.data );

 94      end loop;

 95  end;

 96 

 97  end;

 98  /

Package body created.

 

4.创建测试用户并授权

 

sys@ORCL>create user shall identified by shall;

User created.

 

sys@ORCL>grant connect,resource to shall;

Grant succeeded.

 

sys@ORCL>grant select on sys.v_$statname to shall;

Grant succeeded.

sys@ORCL>grant select on sys.v_$mystat to shall;

Grant succeeded.

sys@ORCL>grant select on sys.v_$latch to shall;

Grant succeeded.

sys@ORCL>grant select on sys.v_$timer to shall;

Grant succeeded.

 

 

sys@ORCL>grant execute on sys.runstats_pkg to shall;

Grant succeeded.

 

5.创建测试表

shall@ORCL>create table test(zhong int);

Table created.

 

shall@ORCL>insert into test select rownum from dual connect by level<=100000;

100000 rows created.

 

6.测试过程

----(1)没有绑定变量的测试过程

shall@ORCL>create or replace procedure p_test1

  2  as

  3  l_cnt number;

  4  begin

  5    for i in 1..100000 loop

  6      execute immediate 'select count(*) from test where zhong=' || i into l_cnt;

  7    end loop;

  8  end;

  9  /

Procedure created.

 

----(2)使用绑定变量的测试过程

shall@ORCL>create or replace procedure p_test2

  2  as

  3  l_cnt number;

  4  begin

  5    for i in 1..100000 loop

  6      select count(*) into l_cnt from test where zhong=i;

  7    end loop;

  8  end;

  9  /

Procedure created.

7.开始测试

sys@ORCL>alter system flush shared_pool;

System altered.

 

shall@ORCL>set serveroutput on;

 

----首先调用runstats_pkg.rs_start,执行没有使用绑定变量的存储过程

shall@ORCL>exec sys.runstats_pkg.rs_start;

PL/SQL procedure successfully completed.

 

shall@ORCL>exec p_test1;

PL/SQL procedure successfully completed.

 

----然后调用runstats_pks.rs_middle,执行绑定变量存储过程

shall@ORCL>exec sys.runstats_pkg.rs_middle;

PL/SQL procedure successfully completed.

 

shall@ORCL>exec p_test2;

PL/SQL procedure successfully completed.

 

----最后生成报告

shall@ORCL>exec sys.runstats_pkg.rs_stop;

8.测试结果对比

可以看到第一个过程硬解析近10w次,执行语句花费了5分多中,而第二个过程仅仅硬解析了7次,执行语句花费了不到2分钟。(时间换算,31750/100/60)

非绑定变量的方式导致了大量的拴锁使用。

 

----两次语句执行分析后,执行runstats_pkg.rs_stop会将不同的信息打印到屏幕上,当然也可以指定打印出数值大于多少的信息。

 

shall@ORCL>exec sys.runstats_pkg.rs_stop;

Run1 ran in 31372 cpu hsecs

Run2 ran in 10888 cpu hsecs

run 1 ran in 288.13% of the time

 

Name                                  Run1        Run2        Diff

STAT...parse time cpu               20,053           2     -20,051

STAT...recursive cpu usage          31,149      10,851     -20,298

STAT...parse time elapsed           20,321           2     -20,319

STAT...CPU used when call star      31,378      10,893     -20,485

STAT...CPU used by this sessio      31,377      10,889     -20,488

STAT...DB time                      31,750      10,986     -20,764

LATCH.checkpoint queue latch        26,947       3,072     -23,875

LATCH.AWR Alerted Metric Eleme      25,267           0     -25,267

LATCH.SQL memory manager worka      41,363       4,145     -37,218

STAT...session cursor cache hi      34,579     -31,047     -65,626

STAT...sql area evicted             97,400           3     -97,397

STAT...table scans (short tabl     200,000     100,001     -99,999

STAT...parse count (hard)          100,014           7    -100,007

STAT...enqueue releases            100,020           8    -100,012

STAT...enqueue requests            100,021           8    -100,013

STAT...opened cursors cumulati     200,119     100,023    -100,096

STAT...execute count               200,145     100,030    -100,115

STAT...calls to get snapshot s     200,151     100,030    -100,121

STAT...session uga memory           58,008     -58,008    -116,016

STAT...Elapsed Time                174,792      17,960    -156,832

STAT...session pga memory           65,536    -131,072    -196,608

STAT...parse count (total)         200,111          24    -200,087

LATCH.call allocation              203,206          41    -203,165

LATCH.enqueue hash chains          213,910         853    -213,057

LATCH.shared pool simulator        408,267         459    -407,808

STAT...recursive calls             701,048     100,171    -600,877

STAT...calls to kcmgcs           1,700,029     800,034    -899,995

LATCH.row cache objects          3,380,124       5,490  -3,374,634

STAT...table scan blocks gotte  25,900,000  21,200,047  -4,699,953

STAT...no work - consistent re  25,900,547  21,200,108  -4,700,439

STAT...consistent gets from ca  27,600,557  22,000,126  -5,600,431

STAT...consistent gets          27,600,806  22,000,166  -5,600,640

STAT...consistent gets from ca  27,600,806  22,000,166  -5,600,640

STAT...session logical reads    27,600,877  22,000,216  -5,600,661

LATCH.shared pool                6,053,904     102,111  -5,951,793

LATCH.cache buffers chains      55,488,477  44,006,437 -11,482,040

STAT...table scan rows gotten ####################################

STAT...logical read bytes from####################################

 

Run1 latches total versus runs -- difference and pct

Run1        Run2        Diff       Pct

67,150,571  45,332,252 -21,818,319    148.13%

 

PL/SQL procedure successfully completed.

 

 

reference                   http://blog.itpub.net/29254281/viewspace-1273911/

 

 

 

9.插入测试(琢行插入和批量插入10000条记录)

----1)环境准备

sys@ORCL>select count(*) from dba_objects;

  COUNT(*)

----------

     86563

sys@ORCL>grant select on dba_objects to shall;

Grant succeeded.

 

shall@ORCL>create table t1 as select * from dba_objects where 1=0;

Table created.

shall@ORCL>create table t2 as  select * from dba_objects where 1=0;

Table created.

 

shall@ORCL>select count(*) from t1;

  COUNT(*)

----------

         0

shall@ORCL>select count(*) from t2;

  COUNT(*)

----------

         0

 

----2)开始测试

----批量插入

shall@ORCL>exec sys.runstats_pkg.rs_start;

PL/SQL procedure successfully completed.

 

shall@ORCL>insert into t1 select * from dba_objects;

86565 rows created.

shall@ORCL>commit;

Commit complete.

 

----琢行插入

shall@ORCL>exec sys.runstats_pkg.rs_middle;

PL/SQL procedure successfully completed.

 

shall@ORCL>begin

  2  for i in (select * from dba_objects) loop

  3    insert into t2 values i;

  4  end loop;

  5  commit;

  6  end;

  7  /

PL/SQL procedure successfully completed.

 

----3)结果对比(只显示数值大于100000的信息)

shall@ORCL>exec sys.runstats_pkg.rs_stop(100000);

Run1 ran in 37 cpu hsecs

Run2 ran in 144 cpu hsecs

run 1 ran in 25.69% of the time

 

Name                                  Run1        Run2        Diff

STAT...session uga memory                0     130,976     130,976

STAT...db block changes              9,801     180,901     171,100

LATCH.cache buffers chains          49,805     484,073     434,268

STAT...undo change vector size     340,568   5,891,368   5,550,800

STAT...redo size                10,131,092  32,885,812  22,754,720

STAT...logical read bytes from 128,696,320 842,702,848 714,006,528

 

Run1 latches total versus runs -- difference and pct

Run1        Run2        Diff       Pct

69,352     620,766     551,414     11.17%

 

PL/SQL procedure successfully completed.

 

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30130773/viewspace-2101594/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30130773/viewspace-2101594/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值