你的大器是你没有理解的性质v$active_session_history
:它是一个样本而不是一个日志。也就是说,ASH 中的每条记录都是一个时间点,并不回溯到以前的记录。
别担心,这是一个常见的错误。
这是WAIT_T
IME 的一个特殊问题。这是等待特定事件发生的总时间。因此,如果等待事件跨越两个样本,则第一个记录中的WAIT_TIME
值为 1(一秒),下一个样本中的值为 2(两秒)。但是,aSUM(WAIT_TIME)
总共会产生3,这太多了。当然,这是一个算术进程,所以如果等待事件延伸到十个样本(十秒),SUM(WAIT_TIME)
那么总共会产生 55 个样本。
基本上,WAIT_TIME
是一个标志 - 如果它是 0,则会话在 CPU 上,如果它大于零,它正在等待。
TIME_WAITED
仅在事件停止等待时填充。所以 a SUM(TIME_WAITED
) 不会给出夸大的值。事实上恰恰相反:它只会为采样时间正在进行的等待事件填充。因此,在该 SUM 中不会出现的样本间隙之间可能会有很多等待。
这就是为什么 ASH 适合突出重大性能问题而不适合识别背景问题的原因。
那么为什么每次运行查询时总时间都不会增加呢?因为 ASH 是一个循环缓冲区。较旧的记录会老化,以便为新样本让路。AWR 将一定百分比的 ASH 记录存储在磁盘上;它们可以通过DBA_HIST_ACTIVE_SESSION_HIST
(默认为十分之一的记录)进行访问。因此,在您运行查询的第二次和第三次之间,ASH 可能会清除一些等待时间较长的样本。您可以通过包含MIN(SAMPLE_TIME)
在选择列表中来检查。
最后,请记住 SID 会被重用。识别会话的主键是(SID, Serial#)
,您的查询仅按 SID 分组,因此它可能使用来自多个不同会话的数据。
格雷厄姆·伍兹(Graham Woods)对从事 ASH 工作的 Oracle 专家进行了一个有用的演示,名为“Shifting through the ASHes”。尽管听格雷厄姆讲话会更好,但幻灯片本身仍然提供了一些有用的见解。 在这里找到它。
tl;博士
ASH 是样本而不是日志。将其用于计数而不是总和。
“查询这些表的方式有什么问题吗?”
正如我上面所说的,但可能还不够清楚,DBA_HIST_ACTIVE_SESSION_HIST
只保存了 ASH 的一小部分记录。因此,SUM()
在其列上运行比在实时 ASH 上运行的意义更小。
而V$SESSION_EVENT
实际的事件日志。它的等待时间可靠且准确。这就是您支付启用定时统计的开销的原因。话虽如此,V$SESSION_EVENT
它只给我们每个会话的聚合值,所以它在诊断中并不是特别有用。