配置环境 - 定制脚本

1.RunStats - 对做同一件事的两个不同方法进行比较,得出孰优孰劣的结果。

RunStats只是测量3个要素:

  • 墙上时钟(wall clock)或耗用时间(elapsed time)
  • 系统统计结果
  • 闩定(latching)

Step1:创建Stats视图

CREATE OR REPLACE VIEW Stats
AS
  SELECT 'STAT...' || sn.NAME NAME,
         ms.VALUE
    FROM v$StatName sn,
         v$MyStat ms
   WHERE sn.Statistic# = ms.Statistic#
  UNION ALL
  SELECT 'LATCH.' || l.NAME,
         l.Gets
    FROM v$Latch l;

Step2:创建一个表来收集统计结果

CREATE GLOBAL TEMPORARY TABLE Run_Stats
(
  RunID VARCHAR2(15),
  Name  VARCHAR2(80),
  Value INT
)
ON COMMIT PRESERVE ROWS;

Step3:创建RunStats_pkg包的说明

CREATE OR REPLACE PACKAGE RunStats_pkg
AS
  PROCEDURE rs_Start;
  PROCEDURE rs_Middle;
  PROCEDURE rs_Stop(p_Difference_Threshold IN NUMBER DEFAULT 0);
END;

Step4:创建RunStats包体

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',
           s.*
      FROM Stats s;

    g_Start := DBMS_UTILITY.GET_TIME;
  END rs_Start;

  PROCEDURE rs_Middle
  IS
  BEGIN
    g_Run1 := DBMS_UTILITY.GET_TIME - g_Start;

    INSERT INTO Run_Stats
    SELECT 'After 1',
           s.*
      FROM Stats s;

    g_Start := DBMS_UTILITY.GET_TIME;
  END rs_Middle;

  PROCEDURE rs_Stop
  (
    p_Difference_Threshold IN NUMBER DEFAULT 0
  )
  IS
  BEGIN
    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('Run1 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',
           s.*
      FROM Stats s;

    DBMS_OUTPUT.PUT_LINE(RPAD('Name', 30) || LPAD('Run1', 10) || LPAD('Run2', 10) || LPAD('Diff', 10));

    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 lathces total versus runs -- difference and pct');
    DBMS_OUTPUT.PUT_LINE(LPAD('Run1', 10) || LPAD('Run2', 10) || LPAD('Diff', 10) || LPAD('Pct', 8));

    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 rs_Stop;
END;

eg.下面的例子对批量插入(INSERT)和逐行处理进行比较,看看哪种方法效率更高

MUZIYU@MYDB> CREATE TABLE t1
  2  AS
  3    SELECT *
  4      FROM Big_Table
  5     WHERE 1 = 0;

表已创建。

MUZIYU@MYDB> CREATE TABLE t2
  2  AS
  3    SELECT *
  4      FROM Big_Table
  5     WHERE 1 = 0;

表已创建。

MUZIYU@MYDB> EXEC RunStats_Pkg.Rs_Start;

PL/SQL 过程已成功完成。

MUZIYU@MYDB> INSERT INTO t1
  2  SELECT *
  3    FROM Big_Table;

已创建1000000行。

MUZIYU@MYDB> COMMIT;

提交完成。

MUZIYU@MYDB> EXEC RunStats_Pkg.Rs_Middle;

PL/SQL 过程已成功完成。

MUZIYU@MYDB> 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 过程已成功完成。

MUZIYU@MYDB> EXEC RunStats_Pkg.Rs_Stop(1000000);
Run1 ran in 7502 hsecs
Run2 ran in 14030 hsecs
Run1 ran in 53.47% of the time
        
Name                           Run1        Run2        Diff
STAT...execute count                   215   1,000,316   1,000,101
LATCH.shared pool                    2,293   1,003,035   1,000,742
STAT...session logical reads       184,145   2,139,195   1,955,050
STAT...db block changes            108,638   2,084,264   1,975,626
STAT...recursive calls               2,283   2,002,931   2,000,648
LATCH.library cache pin              2,356   2,003,292   2,000,936
LATCH.library cache                  3,881   2,005,397   2,001,516
STAT...session pga memory           82,208   4,196,448   4,114,240
STAT...session pga memory max       66,072   4,393,056   4,326,984
LATCH.cache buffers chains         590,988   7,499,318   6,908,330
STAT...redo size               115,567,468 356,828,232 241,260,764
        
Run1 lathces total versus runs -- difference and pct
Run1     Run2        Diff        Pct
856,657  13,952,561  13,095,904  6.14%

PL/SQL 过程已成功完成。

2.MyStat - 用于展示完成某操作之前和之后的某些Oracle“统计结果”的变化情况。

MyStat.SQL:获得结果的开始值

SET ECHO OFF
SET VERIFY OFF
COLUMN Value New_Val V
DEFINE S = "&1"

SET AUTOTRACE OFF
SELECT sn.Name,
       ms.Value
  FROM v$StatName sn,
       v$MyStat ms
 WHERE sn.Statistic# = ms.Statistic#
   AND LOWER(sn.Name) LIKE '%' || LOWER('&S') || '%'
/

SET ECHO ON

MyStat2.SQL:报告统计结果的变化情况(差值)

SET ECHO OFF
SET VERIFY OFF

SELECT sn.Name,
       ms.Value V,
       TO_CHAR(ms.Value - &V, '999999999999') Diff
  FROM v$StatName sn,
       v$MyStat ms
 WHERE sn.Statistic# = ms.Statistic#
   AND LOWER(sn.Name) LIKE '%' || LOWER('&S') || '%'
/

SET ECHO ON

eg.删除表Dept数据,将会生成1940字节的Redo

MUZIYU@MYDB> @D:/SQL/MyStat.SQL "redo size"

NAME                                                             VALUE
---------------------------------------------------------------- ----------
redo size                                                        556

MUZIYU@MYDB> DELETE FROM DEPT;

已删除4行。

MUZIYU@MYDB> @D:/SQL/MyStat2.SQL
MUZIYU@MYDB> SET ECHO OFF

NAME                                                             V          DIFF
---------------------------------------------------------------- ---------- -------------
redo size                                                        2496       1940

软件环境:Windows XP SP3+Oracle 9i R2,[ORACLE_HOME]=C:/Oracle/Ora92

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值