在监控、诊断、处理数据库性能问题的时候,时间信息往往是非常重要的判定依据。有时候可能我们会使用一些比例来判定性能,但是使用比例而不使用时间往往会将我们带向错误的方向。在Oracle9i的第一版中关于时间的信息被进行了增强,提供了更多更有益的时间信息。
除了9i的外貌发生了变化,在一些并没有被我们注重或者不为人知得一些v$视图的相关字段也发生了变化。这里提到的主要是他们发生了那些改变以及对DBA有什么帮助。这里也列出了零星的一些Oracle内部的未公开的信息。
Second 1 秒
Centi-second 1/100 百分之一秒 厘秒
Milli Second 1/1000 千分之一秒 毫秒
Micro Second 1/1.000.000 微妙
Nano Second 1/1.000.000.000 纳秒
在以前的版本中,Oracle的时间计量单位是厘秒,使用厘秒最显而易见的问题就是可能有些操作是小于厘秒的。看上去这似乎不太常见,但是实际上在操作系统上很多操作都是以微妙作为单位的,这意味着操作的起始和终止在不到厘秒就完成了,从厘秒级看就似乎没有发生一样,因为持续时间近似为0。而有时候操作的持续时间不到厘秒,但是起始和终止发生在两个相连的厘秒,所以操作时间不到厘秒但是却被记录为厘秒,造成时间记录的不准确。
在Oracle9i之前,最小的时间单位仍然是厘秒,这可以在跟踪文件、v$system_event和v$session_event中的超时字段看到。在9i之前,是不能在联机状态看到sql语句的执行(cpu消耗)时间和持续时间的,也不能看到一条Sql语句在等待着什么,实际上只有一种方法可以得到这些信息,就是通过启用10046 trace level 12的跟踪事件。这样做也会带来下面的一些问题:
1. 生成进程跟踪文件带来很高的性能开销
2. 假如有太多用于帮助调优的sql语句执行,将会产生大量的磁盘/文件空间需求。
在oracle9i第一版中的持续时间以微妙作为时间单位,这能够显示出Oracle真正花费的时间。超时仍然以微妙作为计时单位。一些视图被扩展以便记录微妙数据。所有的时间信息由初始化参数timed_statistics 决定。
一些视图的改变:
V$SQLAREA:
两个字段被加入到V$SQLAREA中,分别是CPU_TIME 和ELAPSED_TIME。两个字段都被设置为微妙级。然而,在这里可能会s看到一个有趣的现象:
Select cpu_time, elapsed_timeFrom v$sqlareaOrder by 2CPU_TIME ELAPSED_TIME---------- ------------230000 174567260000 258803260000 271808首先:三行中的第二行显示出了持续时间小于cpu执行时间,实际的情况是cpu字段记录单位是微妙级,但是数据被进位保留到了厘秒级。
Sql语句的等待时间等于ELAPSED_TIME减去CPU_TIME,但是很难看到精确的等待时间。在V$SYSTEM_EVENT 视图中能够看到数据库实例级的等待时间(并不是每条Sql语句的),但是看不到发生在操作系统上(cpu等待、内存的等待)的等待时间s。
X$KSQST的改变 (对应视图V$ENQUEUE_STAT)
基础表X$KSQST主要显示关于系统中队列的信息。在9i之前只能提供队列类型的get和wait数。一个队列有两种特征和两个标识组成(id1 and id2)。例如一个叫做TX队列,表示一个事务队列。从Oracle9i开始不但能够看到gets 和waits,而且等待的时间和得不到队列(中断或者超时)的失败次数都可以看到。
X$KSQST
KSQSTWTIM NUMBER 以微妙作为单位
然而这里仍不能将队列等待与Sql语句关联,也不能够得到等待队列的Sql语句到底等待了多久。下面的一个新的视图v$enqueue_stat 将提供关于队列得更多信息:
V$ENQUEUE_STATINST_ID NUMBEREQ_TYPE VARCHAR2TOTAL_REQ# NUMBERTOTAL_WAIT# NUMBERSUCC_REQ# NUMBERFAILED_REQ# NUMBERCUM_WAIT_TIME NUMBERV$SYSSTAT的改变
实际这个视图并没有什么改变,关于时间的信息仍然在厘秒级。
V$SYSSTAT
CPU used by this session 厘秒
Parse time cpu 厘秒
Parse time 厘秒
Recursive cpu usage 厘秒
当从不同资源中比较数据时应该注重。
V$WAITSTAT的改变
这个视图显示了发生在块级的buffer busy waits的细目描述,等待时间的单位在微妙级。
V$WAITSTAT
TIME NUMBER 厘秒单位
这里无法通过视图中出现的等待找到对应的sql语句。
V$FILESTAT的改变
在这个视图中现在分成了单次块读取和累计块读取,这种分法更合理。
V$FILESTAT
MAXIORTM NUMBER 厘秒级的最大读取时间
MAXIOWTM NUMBER 厘秒级的最大写入时间
SINGLEBLKRDS NUMBER 单次块读取块数
SINGLEBLKRDTIM NUMBER 厘秒级的累计单次块读取时间
这个视图也不能找到相关的Sql语句,使用dbms_system.kcfrms()过程可以重设最大读、写时间,设置更准确的取样间隔。
V$SESSION_EVENT的改变
这个视图现在已经可以捕捉到微妙级的等待事件的持续时间了。它可以以微妙或者厘秒方式显示等待时间,因为这些改变,等待事件变得更加精确(等待时间以微妙方式捕捉,然后转换为厘秒方式)
V$SESSION_EVENT
TIME_WAITED_MICRO NUMBER 以微妙级等待的时间
TIME_WAITED NUMBER 微妙级的等待时间 / 10000
MAX_WAIT NUMBER 厘秒级的最大等待时间
当然,这个视图也不能找到相关的Sql语句。
一个被大多数DBA所感爱好的字段是MAX_WAIT 字段,这个字段显示了一个事件的最大等待时间。这个信息只要会话一登陆就生效,将显示一个会话整个生命期中的最大等待时间。使用dbms_system.kcfrms() 过程可以重置最大的值,以便让这个字段显示与测量周期更紧密的值。
V$SYSTEM_EVENT的改变
这个视图最主要的变化是增加了TIME_WAITED_MICRO字段,它以微妙为单位显示了持续的时间。.另外TIME_WAITED 也更加精确,,因为它来自于TIME_WAITED_MICRO的值。
PARSING IN CURSOR #1 len=29 dep=0 uid=5 oct=3 lid=5 tim=1006862415399006 hv=438451932 ad='84b05c04'select count(*) from tab, tabEND OF STMTPARSE #1:c=10000,e=11334,p=0,cr=4,cu=0,mis=1,r=0,dep=0,og=4,tim=1006862415398976BINDS #1:EXEC #1:c=0,e=587,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1006862415399931WAIT #1: nam='SQL*Net message to client' ela= 10 p1=1650815232 p2=1 p3=0FETCH #1:c=2500000,e=2526458,p=0,cr=149542,cu=0,mis=0,r=1,dep=0,og=4,tim=1006862417926777WAIT #1: nam='SQL*Net message from client' ela= 1004 p1=1650815232 p2=1 p3=0FETCH #1:c=0,e=6,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=1006862417928426WAIT #1: nam='SQL*Net message to client' ela= 7 p1=1650815232 p2=1 p3=0WAIT #1: nam='SQL*Net message from client' ela= 3636276 p1=1650815232 p2=1 p3=0注重:时间都是微妙级的,但是这里仍然有一些很有意思的地方:
1. tim= 明显是微妙级的,这个tim 域给出了一个时间快照
2. e= 和 ela= 也是微妙级的,这两个域表示持续的事件
3. 比较有趣的是c=. 看上去似乎是微妙级的,但是实际上是厘秒级的数据乘上了10000, 域c 表示cpu的消耗
v$latch, / v$latch_parent / v$latch_children 的改变:
在Oracle9i主要的改变是增加了wait_time字段。因此现在锁存器竞争更轻易检测了,而在Oracle9i以前,只能通过察看sleeps次数来判定。在v$latch中主要相关的字段包括:
V$LATCH
NAME VARCHAR(64) 锁存器名称.
SLEEPS NUMBER 锁存器由于忙而产生的sleep次数
SLEEP1..11 NUMBER 显示了sleep的分布情况
WAIT_TIME NUMBER 微妙级的等待时间
在Orace9i以前与v$latch的 ‘latch free’等待事件的SLEEPS字段对应的是v$system_event的TOTAL_WAITS字段:
select event, total_waits, time_waitedfrom v$system_eventwhere event = 'latch free'select name, trunc(sleeps*100/ total, 2) "Perc of Sleeps"from v$latch, (select decode(sum(sleeps), 0, 1, sum(sleeps)) total from v$latch)where sleeps != 0有很多sleeps的锁存器会显示为v$system_event的大量等待时间。在Oracle9i由于在v$latch中有了WAIT_TIME字段,所以提供了更准确的信息:
select name, trunc(wait_time*100/time_waited, 2) "Perc. of Time Waited"
from v$latch, (select time_waited from v$system_event where event = 'latch free')where wait_time != 0order by 2还有那些没有改变?
其他与时间相关的信息都没有改变。在V$SYSSTAT中象 ‘CPU used by this session’, ‘parse cpu time’ and ‘recursive cpu usage’等事件仍然表示为厘秒。
Oracle没有改变这些统计信息的单位是因为这些信息可能会影响着一些依靠于他们的应用或者脚本。
Oracle的PRecise/Indepth
在Oracle9i中由于使用了微妙做为单位,所以持续时间已经变得更加准确,但是仍然不能看到在一个特定的时间范围内的每个sql语句的资源消耗。了解每个sql语句的资源消耗能够帮助你确定那个sql语句是你首先应该调优的。 使用Oracle的Precise/Indepth,通过不断的监视Oracle的环境,收集用于性能分析的数据,就能够看到每条Sql语句的资源消耗情况。这些资源消耗情况最终被细分为:
Using CPU
CPU wait
I/O wait
Memory wait
Other host wait
Table lock wait
Row lock wait
Shared pool wait
Buffer wait
Rollback segment wait
Redo log buffer wait
Log switch and clear wait
Internal lock wait
Background process wait
Parallel query sync. Wait
Parallel query server wait
Other wait