正确的计算方法"总等待时间"在oracle中的会话

时间:2013-01-08 10:54:11

标签: performance oracle session wait

我需要查看会话处于活动状态时等待的总时间。

为此我使用了如下的查询......

SELECT (SUM (wait_time + time_waited) / 1000000)
  FROM v$active_session_history
 WHERE session_id = 614 

但是,我觉得我没有得到我想要使用此查询的内容。 就像,第一次运行此查询时,我得到145.980962,@第二次= 145.953926,@第三次得到127.706429。

理想情况下,时间应相同或增加。但是,如您所见,返回的值每次都在减少。

请纠正我在哪里做错了。

2 个答案:

答案 0 :(得分:3)

它不包含整个历史记录,v$active_session_history“忘记”旧行。把它想象成一个缓冲环。写入所有缓冲区后,它将从第一个缓冲区重新启动。
要获取某个会话的事件,请查看v$session_event
获取活动会话的当前(活动)事件:v$session_wait(在最近的Oracle版本中,您也可以在v$session中找到此信息)
注意: v $ session_event视图不会显示CPU时间(这不是事件,但可以在v$active_session_history中看到)。例如,您可以根据需要v$sesstat添加它...

答案 1 :(得分:0)

你的笨蛋是你没有理解v$active_session_history的本质:它是样本而不是日志。也就是说,ASH中的每个记录都是一个时间点,并且不会返回先前的记录。

别担心,这是一个常见的错误。

这是WAIT_T IME的一个特殊问题。这是等待该事件发生的特定事件的总时间。因此,如果等待事件延伸到两个样本,则第一个记录WAIT_TIME将为1(一秒),而在下一个样本中,它将为2(两秒)。但是,SUM(WAIT_TIME)会产生总计 3 ,这太多了。当然这是一个算术预测,所以如果等待事件延伸到十个样本(十秒),SUM(WAIT_TIME)将产生总共55个。

基本上,WAIT_TIME是一个标志 - 如果它是0,则会话在CPU上,如果它大于零,则它是WAITING。

仅在事件停止等待时才填充

TIME_WAITED。所以SUM(TIME_WAITED)不会给出夸大的价值。事实恰恰相反:它只会填充在样本时间正在进行的等待事件。因此,样本的间隙之间可能存在大量等待,这些等待不会出现在该SUM中。

这就是为什么ASH有利于突出重大性能问题而不利于识别背景问题。

那么为什么每次运行查询时总时间不会增加?因为ASH是一个循环缓冲区。较旧的记录会老化,以便为新样本让路。 AWR将一定比例的ASH记录存储在磁盘上;它们可以通过DBA_HIST_ACTIVE_SESSION_HIST访问(默认为十分之一)。因此,ASH可能会在您运行查询的第二次和第三次之间清除一些等待时间较长的样本。您可以通过在选择列表中包含MIN(SAMPLE_TIME)来检查。

最后,请记住SID可以重复使用。用于标识会话的主键是(SID, Serial#),您的查询仅通过SID进行查询,因此它可以使用来自多个不同会话的数据。

格雷厄姆·伍兹(Graham Woods)在ASH工作的甲骨文大师中有一个有用的演讲,名为“通过ASHes转移”。如果听到格雷厄姆说话会更好,那么幻灯片本身仍然提供了一些有用的见解。 Find it here

<强> TL;博士

ASH是一个样本而非日志。将它用于COUNTs而不是SUMs。


  

“查询这些表的方式有什么问题吗?”

正如我上面所说,但也许没有说清楚,DBA_HIST_ACTIVE_SESSION_HIST只能保留ASH记录的一小部分。因此,在其列上运行SUM()比在实时ASH上运行更有意义。

V$SESSION_EVENT是事件的实际日志。它的等待时间可靠而准确。这就是您支付启用timed statistics的开销的原因。说过哪一个,V$SESSION_EVENT只给出了每个会话的汇总值,所以它在诊断中并不是特别有用。