发表于: 2008.03.21 22:03
分类: 读书笔记
出处: http://yangtingkun.itpub.net/post/468/457861
---------------------------------------------------------------
今天在看Tom的新书Oracle9i&10g编程艺术发现了一个小问题。
Tom在这本书开头部分介绍了他自己的常用工具,其中包括mystat脚本。这个脚本的目的是获取一个操作的某个统计结果变化情况。
其中由两个脚本构成,mystat记录状态的初始状态,mystat2记录最终状态,并显示差异。
书中给出的mystat脚本如下:
SET ECHO OFF
SET VERIFY OFF
COLUMN VALUE NEW_VAL V
DEFINE S="&1"
SET AUTOTRACE OFF
SELECT A.NAME, B.VALUE
FROM V$STATNAME A, V$MYSTAT B
WHERE A.STATISTIC# = B.STATISTIC#
AND LOWER(A.NAME) LIKE '%' || LOWER('&S') || '%'
/
SET ECHO ON
另一个脚本mystat2如下:
SET ECHO OFF
SET VERIFY OFF
SELECT A.NAME, B.VALUE V, TO_CHAR(B.VALUE - &V, '999,999,999,999') DIFF
FROM V$STATNAME A, V$MYSTAT B
WHERE A.STATISTIC# = B.STATISTIC#
AND LOWER(A.NAME) LIKE '%' || LOWER('&S') || '%'
/
SET ECHO ON
看一下这两个脚本的使用:
SQL> @e:mystat "undo change vector size"
SQL> SET ECHO OFF
NAME VALUE
------------------------------ ----------
undo change vector size 0
SQL> delete t;
已删除4行。
SQL> @e:mystat2
SQL> SET ECHO OFF
NAME V DIFF
------------------------------ ---------- ----------------
undo change vector size 1592 1,592
书中给出的例子没有任何的问题,但是脚本本身存在问题。
由于Tom使用了SQLPLUS的NEW_VALUE功能来获取前后两次统计结果的差异,因此这个功能仅对单个统计项有效。
但是Tom给出的脚本中在输入的统计项两边追加了%,使得统计项可以模糊匹配,这虽然方便了查询输入,但是很容易造成输入的关键字匹配多个统计项。而一旦出现这种情况,则MYSTAT2脚本中的差异统计就会完全错误:
SQL> @e:mystat "redo"
SQL> SET ECHO OFF
NAME VALUE
------------------------------ ----------
redo synch writes 1
redo synch time 1
redo blocks read for recovery 0
redo entries 6
redo size 4152
redo buffer allocation retries 0
redo wastage 0
redo writer latching time 0
redo writes 0
redo blocks written 0
redo write time 0
redo log space requests 0
redo log space wait time 0
redo log switch interrupts 0
redo ordering marks 0
redo subscn max counts 0
IMU Redo allocation size 1248
已选择17行。
SQL> create table t_redo as select * from dba_objects;
表已创建。
SQL> @e:mystat2
SQL> SET ECHO OFF
NAME V DIFF
------------------------------ ---------- ----------------
redo synch writes 3 -1,245
redo synch time 1 -1,247
redo blocks read for recovery 0 -1,248
redo entries 1223 -25
redo size 5817596 5,816,348
redo buffer allocation retries 0 -1,248
redo wastage 0 -1,248
redo writer latching time 0 -1,248
redo writes 0 -1,248
redo blocks written 0 -1,248
redo write time 0 -1,248
redo log space requests 0 -1,248
redo log space wait time 0 -1,248
redo log switch interrupts 0 -1,248
redo ordering marks 20 -1,228
redo subscn max counts 0 -1,248
IMU Redo allocation size 1248 0
已选择17行。
这个结果已经很清晰的说明了问题,因此这里应该将脚本从LIKE方式改为等于的方式,这样可以避免错误的发生。











