配置环境runstats

  runstats是一个开发工具,能对同一件事的两个不同方法进行比较,得出孰优孰劣的结果。你只要提供两个不同的方法,余下的事情都由runstats负责。runstats只是测量3个要素:

  • 墙上时钟(wall clock)或耗用时间(elapsed time):知道墙上时钟或耗用时间很有用,不过这不是最重要的信息。
  • 系统统计结果:会并排地显示每个方法做某件事(如执行一个解析调用)的次数,并展示出二者之差。
  • 闩定(latching):这是这个报告的关键输出。

  闩(latch)是一种轻量级的锁。锁(lock)是一种串行化设备,而串行化设备不支持并发。如果应用不支持并发,可扩缩性就比较差,只能支持较少的用户,而且需要更多的资源。构建应用时,我们往往希望应用能很好地扩缩,也就是说,为1位用户服务与为1000或10 000位用户服务应该是一样的。应用中使用的闩越少,性能就越好。如果一种方法从墙上时钟来看运行时间较长,但是只使用了另一种方法10%的闩,这时候就可能会选择前者。与使用更多闩的方法相比,使用较少闩的方法能更好地扩缩。

  runstats最好独立使用,最好在一个单用户数据库上运行。我们会测量各个方法的统计结果和闩定(锁定)活动。runstats在运行过程中,不希望其他任务对系统的负载或闩产生影响。只需一个小的测试数据库就能很好地完成这些测试。

  要使用runstats需要能访问几个V$视图,并创建一个表来存储统计结果,还要创建runstats包。为此,需要访问3个V$表(就是那些神奇的动态性能表):V$STATNAME、V$MYSTAT和V_$LATCH。

1.创建视图:

先要授权给system

SQL> grant select on v_$session to system;

授权成功。

SQL> grant select on v_$statname to system;

授权成功。

SQL> grant select on v_$mystat to system;

授权成功。

SQL> grant select on v_$latch to system;

授权成功。

SQL> grant select on v_$timer to system;

授权成功。

SQL>  create or replace view stats
  2   as
  3   select 'STAT...' || a.name name, b.value
  4   from v_$statname a, v_$mystat b
  5   where a.statistic# = b.statistic#
  6   union all
  7   select 'LATCH.' || name, gets
  8  from v_$latch;

视图已创建。

2.建立一个小表收集统计结果:

SQL> create global temporary table run_stats
  2  (runid varchar2(15),
  3  name varchar2(80),
  4  value int)
  5  on commit preserve rows;

表已创建。

3.创建runstats包。其中包含3个简单的API调用:

  • runstats测试开始时调用RS_START(runstats开始)。
  • 正如你想象的,RS_MIDDLE会在测试中间调用。
  • 完成时调用RS_STOP,打印报告。

runstats包:

SQL> 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  /

程序包已创建。

  参数P_DIFFERENCE_THRESHOLD用于控制最后打印的数据量。runstats会收集并得到每次运行的统计结果和闩信息,然后打印一个报告,说明每次测试(每个方法)使用了多少资源,以及不同测试(不同方法)的结果之差。可以使用这个输入参数来控制只查看差值大于这个数的统计结果闩信息。由于这个参数默认为0,所以默认情况下可以看到所有输出。

分析1:包前面是一堆全局变量,这些全局变量用于记录每次运行的耗用时间:

SQL> create or replace package body runstats_pkg
  2  as
  3
  4  g_start number;
  5  g_run1 number;
  6  g_run2 number;
  7
  8  /*RS_start例程。清空保存统计结果的表,并填入"上一次"(before)得到的
  9  统计结果和闩信息。然后获得当前定时器值,这是一种时钟,可用于计算耗用时间
 10  */
 11  procedure rs_start
 12  is
 13  begin
 14      delete from run_stats;
 15
 16      insert into run_stats
 17      select 'before', stats.*
 18      from stats;
 19
 20      g_start := dbms_utility.get_time;
 21  end;
 22
 23  /*RS_MIDDLE例程
 24  把第一次测试运行的耗用时间记录在g_run1中。
 25  然后插入当前的一组统计结果和闩信息。
 26  如果把这些值与先前在RS_START中保存的值相减,就会发现第一个方法使用了
 27  多少闩,以及使用了多少游标(一种统计结果)
 28  */
 29  procedure rs_middle
 30  is
 31  begin
 32     g_run1 := (dbms_utility.get_time - g_start);
 33
 34     insert into run_stats
 35     select 'after 1', stats.*
 36     from stats;
 37
 38     g_start := dbms_utility.get_time;
 39  end;

 40
 41  procedure rs_stop(p_difference_threshold in number default 0)
 42  is
 43  begin
 44     g_run2 := (dbms_utility.get_time - g_start);
 45
 46     dbms_output.put_line
 47             ('Run1 ran in ' || g_run1 || ' hsecs');
 48     dbms_output.put_line
 49             ('Run2 ran in ' || g_run2 || ' hsecs');
 50     dbms_output.put_line
 51             ('Run 1 ran in ' || round(g_run1 / g_run2 * 100, 2) ||
 52             '% of the time');
 53     dbms_output.put_line(chr(9));
 54
 55     insert into run_stats
 56     select 'after 2', stats.*
 57     from stats;
 58
 59     dbms_output.put_line
 60     (rpad('Name',30) || lpad('Run1',10) ||
 61     lpad('Run2',10) || lpad('Diff',10));
 62
 63     for x in
 64     (select rpad(a.name,30) ||
 65             to_char(b.value - a.value, '9,999,999') ||
 66             to_char(c.value - b.value, '9,999,999') ||
 67             to_char(((c.value - b.value) - (b.value - a.value)),'9,999,999') data
 68     from run_stats a, run_stats b, run_stats c
 69     where a.name = b.name
 70     and b.name = c.name
 71     and a.runid = 'before'
 72     and b.runid = 'after 1'
 73     and c.runid = 'after 2'
 74     and (c.value - a.value) > 0
 75     and abs((c.value - b.value) - (b.value - a.value))
 76             > p_difference_threshold
 77     order by abs((c.value - b.value) - (b.value - a.value))
 78     )loop
 79             dbms_output.put_line(x.data);
 80     end loop;

 81
 82     dbms_output.put_line(chr(9));
 83
 84     dbms_output.put_line
 85     ('Run1 latches total versus runs -- difference and pct');
 86     dbms_output.put_line
 87     (lpad('Run1',10) || lpad('Run2',10) ||
 88     lpad('Diff',10) || lpad('Pct',8));
 89
 90     for x in
 91     (select to_char(run1,'9,999,999') ||
 92             to_char(run2,'9,999,999') ||
 93             to_char(diff,'9,999,999') ||
 94             to_char(round(run1/run2 * 100,2), '999.99') || '%' data
 95     from (select sum(b.value - a.value) run1, sum(c.value - b.value) run2,
 96                     sum((c.value - b.value) - (b.value - a.value)) diff
 97             from run_stats a, run_stats b, run_stats c
 98             where a.name = b.name
 99             and b.name = c.name
100             and a.runid = 'before'
101             and b.runid = 'after 1'
102             and c.runid = 'after 2'
103             and a.name like 'LATCH%'
104             )
105     )loop
106             dbms_output.putline(x.data);
107     end loop;
108  end;
109
110  end;

111  /

程序包体已创建。


 下面使用runstats,通过例子说明如何使用runstats对批量插入(INSERT)和逐行处理进行比较,看看哪种方法效率更高。

首先建立两个表,需要插入1 000 000行记录:

SQL> @C:\Users\Binio\Desktop\scripts\chapter00\big_table.sql

表已创建。


表已更改。

输入 1 的值:  1000000
原值    3:     l_rows number := &1;
新值    3:     l_rows number := 1000000;
输入 1 的值:  1000000
原值    9:       where rownum <= &1;
新值    9:       where rownum <= 1000000;

PL/SQL 过程已成功完成。


表已更改。


PL/SQL 过程已成功完成。


  COUNT(*)
----------
   1000000


SQL> create table t1
  2  as
  3  select * from big_table
  4  where 1 = 0;

表已创建。

SQL> create table t2
  2  as
  3  select * from big_table
  4  where 1 = 0;

表已创建。


现在使用第一种方法插入记录,使用单独一条SQL语句完成批量插入。

首先调用RUNSTATS_PKG.RS_START:

SQL> exec runstats_pkg.rs_start;

PL/SQL 过程已成功完成。

SQL> insert into t1 select * from big_table;

已创建1000000行。

SQL> commit;

提交完成。

SQL> exec runstats_pkg.rs_middle;

PL/SQL 过程已成功完成。

SQL> begin
  2  for x in (select * from big_table)
  3  loop
  4     insert into t2 values X;
  5  end loop;
  6  commit;
  7  end;
  8  /

PL/SQL 过程已成功完成。

SQL> exec runstats_pkg.rs_stop;
Run1 ran in 4916 hsecs
Run2 ran in 19192 hsecs
Run 1 ran in 25.61% of the time

Name                                Run1      Run2      Diff
LATCH.global KZLD latch for me         1         2         1
STAT...table fetch by rowid            3         2        -1
STAT...IMU Flushes                     0         1         1
STAT...parse time elapsed              2         3         1
STAT...index fetch by key             88        87        -1
STAT...rows fetched via callba         3         2        -1
LATCH.archive control                  0         2         2
LATCH.event group latch                2         4         2
STAT...global undo segment hin         0         2         2
STAT...SQL*Net roundtrips to/f         6         4        -2
STAT...parse count (hard)              1         3         2
STAT...buffer is not pinned co       176       174        -2
STAT...consistent changes            103       105         2
STAT...deferred (CURRENT) bloc        85        88         3
STAT...parse time cpu                  1         4         3
LATCH.JS slv state obj latch           3         6         3
STAT...user calls                      9         6        -3
LATCH.threshold alerts latch           2         5         3
STAT...commit txn count during         6         9         3
LATCH.resmgr:actses change gro         2         5         3
LATCH.kks stats                        0         4         4
LATCH.job_queue_processes para         2         6         4
LATCH.OS process: request allo         3         8         5
LATCH.channel handle pool latc         3         8         5
LATCH.parameter table allocati         2         7         5
LATCH.process group creation           3         8         5
LATCH.process allocation               3         8         5
LATCH.Shared B-Tree                    2         7         5
LATCH.list of block allocation       469       474         5
LATCH.kwqbsn:qsga                      2         7         5
STAT...redo buffer allocation         17        22         5
LATCH.session state list latch         9        14         5
LATCH.transaction allocation           3         9         6
STAT...write clones created in         2         9         7
LATCH.FOB s.o list latch               2         9         7
LATCH.KWQMN job cache list lat         3        11         8
LATCH.resmgr:free threads list         5        14         9
LATCH.resmgr:actses active lis         5        14         9
LATCH.dummy allocation                 5        14         9
LATCH.parameter list                  10         0       -10
LATCH.ncodef allocation latch          1        11        10
LATCH.transaction branch alloc         1        11        10
LATCH.sort extent pool                 1        11        10
LATCH.user lock                        4        14        10
LATCH.library cache pin alloca         8        18        10
LATCH.session switching                1        11        10
LATCH.ksuosstats global area           3        13        10
LATCH.resmgr group change latc         7        18        11
STAT...commit cleanouts succes     4,745     4,760        15
LATCH.PL/SQL warning settings         24        39        15
STAT...commit cleanouts            4,749     4,764        15
LATCH.OS process                       9        24        15
LATCH.parallel query alloc buf         8        24        16
STAT...redo log space requests         6        23        17
LATCH.qmn task queue latch             8        28        20
LATCH.library cache lock alloc        38        84        46
LATCH.KMG MMAN ready and start        16        64        48
LATCH.post/wait queue                 48       100        52
LATCH.session timer                   17        71        54
LATCH.client/application info         36        92        56
LATCH.OS process allocation           23        80        57
STAT...enqueue conversions             0        63        63
LATCH.AWR Alerted Metric Eleme        66         1       -65
STAT...user I/O wait time            157       235        78
LATCH.loader state object free         0        96        96
STAT...physical read total mul       631       527      -104
LATCH.SGA IO buffer pool latch       631       527      -104
STAT...calls to kcmgcs            14,367    14,481       114
STAT...physical read total IO        643       528      -115
STAT...physical read IO reques       643       528      -115
STAT...hot buffers moved to he         0       119       119
LATCH.shared pool                  1,490     1,622       132
LATCH.shared pool simulator          108       241       133
STAT...session cursor cache hi       172       359       187
STAT...table scans (short tabl        85       273       188
STAT...parse count (total)           176       365       189
STAT...opened cursors cumulati       176       371       195
LATCH.multiblock read objects      1,278     1,056      -222
LATCH.ASM db client latch             45       295       250
LATCH.file cache latch                85       346       261
STAT...physical reads cache pr     8,172     7,901      -271
LATCH.Consistent RBA                 118       411       293
LATCH.lgwr LWN SCN                   125       428       303
LATCH.active service list            111       414       303
LATCH.mostly latch-free SCN          125       429       304
LATCH.compile environment latc        60       385       325
STAT...messages sent                 103       484       381
STAT...physical reads cache        8,815     8,429      -386
STAT...physical reads              8,815     8,429      -386
STAT...bytes sent via SQL*Net      1,165       766      -399
STAT...bytes received via SQL*     1,664     1,188      -476
LATCH.dml lock allocation            395     1,045       650
STAT...enqueue releases            3,339     4,001       662
STAT...enqueue requests            3,338     4,001       663
LATCH.In memory undo latch           155       846       691
STAT...calls to get snapshot s       442     1,221       779
LATCH.session idle bit               353     1,156       803
STAT...redo log space wait tim        20       886       866
LATCH.JS queue state obj latch       360     1,368     1,008
STAT...IMU undo allocation siz     2,012       880    -1,132
LATCH.library cache lock             805     2,181     1,376
LATCH.channel operations paren       388     1,956     1,568
STAT...change write time             258     2,072     1,814
LATCH.library cache pin              976     2,800     1,824
LATCH.redo allocation                673     2,553     1,880
LATCH.object queue header heap       411     2,432     2,021
LATCH.active checkpoint queue        413     2,472     2,059
STAT...dirty buffers inspected         2     3,182     3,180
LATCH.redo writing                   808     3,998     3,190
LATCH.SQL memory manager worka     1,082     4,386     3,304
LATCH.library cache                1,883     5,399     3,516
LATCH.enqueues                     7,213    11,448     4,235
LATCH.enqueue hash chains          7,766    12,549     4,783
LATCH.row cache objects            2,217     7,305     5,088
STAT...recursive cpu usage            13     5,323     5,310
LATCH.cache buffer handles         5,644         0    -5,644
STAT...CPU used when call star       501     6,297     5,796
STAT...CPU used by this sessio       498     6,297     5,799
STAT...DB time                       730     7,689     6,959
LATCH.messages                     1,653     8,857     7,204
STAT...free buffer requested      23,732    31,005     7,273
STAT...redo ordering marks         3,371    11,044     7,673
STAT...calls to kcmgas             3,544    11,244     7,700
STAT...redo subscn max counts     14,843    22,549     7,706
STAT...consistent gets from ca    45,349    53,516     8,167
STAT...consistent gets            45,349    53,516     8,167
LATCH.session allocation             135     9,309     9,174
STAT...Cached Commit SCN refer    14,359    24,157     9,798
STAT...no work - consistent re    14,662    24,866    10,204
STAT...table scan blocks gotte    14,583    24,787    10,204
STAT...IMU Redo allocation siz       312    11,072    10,760
STAT...active txn count during     1,585    13,166    11,581
STAT...cleanout - number of kt     1,591    13,173    11,582
STAT...consistent gets - exami     1,855    13,442    11,587
LATCH.undo global data             2,175    15,648    13,473
STAT...free buffer inspected       5,257    30,769    25,512
LATCH.checkpoint queue latch       6,194    48,042    41,848
LATCH.cache buffers lru chain     30,722    95,001    64,279
LATCH.simulator lru latch          9,106    99,487    90,381
LATCH.simulator hash latch        14,246   106,080    91,834
LATCH.object queue header oper    49,171   155,017   105,846
STAT...table scan rows gotten  1,001,020 1,689,466   688,446
STAT...redo entries               73,679 1,047,947   974,268
STAT...buffer is pinned count    985,587         0  -985,587
STAT...db block gets              80,674 1,071,949   991,275
STAT...db block gets from cach    80,674 1,071,949   991,275
STAT...session logical reads     126,023 1,125,465   999,442
STAT...execute count                 176 1,000,364 1,000,188
STAT...recursive calls             2,638 1,014,318 1,011,680
STAT...db block changes          118,639 2,074,040 1,955,401
STAT...physical read total byt####################-3,162,112
STAT...physical read bytes    ####################-3,162,112
LATCH.cache buffers chains       519,544 5,676,060 5,156,516
STAT...undo change vector size 3,722,088####################
STAT...redo size              ##############################

Run1 latches total versus runs -- difference and pct
Run1      Run2      Diff     Pct
669,540 6,285,021 5,615,481  10.65%

PL/SQL 过程已成功完成。

原文地址:https://www.cnblogs.com/benio/p/1618201.html