Oracle - 找不到长时间运行的查询

3

我在这里漏掉了什么?我正在尝试测试识别长时间运行的查询。

我有一个名为mytest的测试表,大约有4亿行。 我在sqlplus中运行了select * from mytest

在另一个窗口中,我运行了下面的脚本来查看我的长时间运行查询

select s.username, s.sid, s.serial#, s.schemaname, 
    s.program, s.osuser, s.status, s.last_call_et
    from v$session s
where last_call_et >= 1 – this is just for testing

我的长时间运行的查询在上面的查询结果中没有显示出来。如果我将条件更改为>=0,那么我会看到我的查询状态显示为INACTIVE,last_call_et为0,尽管查询仍在运行。我该怎么做才能像上面的select * from...一样看到我的长时间运行的查询并杀死它?

谢谢

2个回答

3
首先,您需要理解诸如select * from mytest这样的查询在幕后实际上正在执行什么操作,因为通常这不会是一个长时间运行的查询。 Oracle 永远不需要使该结果集具体化,并且不会在单个调用的结果上读取所有数据。 相反,发生了一系列调用,每个调用都会导致 Oracle 做一些工作。 对话大致如下:
  • 客户端:嘿 Oracle,请为我运行查询:select * from mytest
  • Oracle:没问题(last_call_et 重置为 0,以反映新调用已启动)。 我生成了一个查询计划并打开了一个游标,这里是一个句柄(请注意,实际上尚未执行查询)
  • 客户端:很酷,谢谢。使用此游标句柄,获取下一批 50 行数据(提取大小是客户端设置)
  • Oracle:好的(last_call_et 重置为 0,以反映新调用已启动)。 我开始全表扫描,读取了几个块,并获得了 50 行。 给你。
  • 客户端:好的,我已经处理完毕。使用此游标句柄,获取下一批 50 行数据
  • 重复此步骤,直到获取所有数据
在此过程中,Oracle 实际上从未被要求执行更多操作以获取 50 行数据(或客户端请求的提取大小)。 在任何时候,客户端都可以简单地不请求下一批数据,因此 Oracle 不需要执行任何长时间运行的操作。 Oracle 不跟踪应用程序在请求更多数据之间的思考时间,它不知道客户端是一个 GUI,正在紧密循环获取数据,还是正在向人显示结果并等待人按“下一步”按钮。 绝大多数情况下,会话将处于INACTIVE状态,因为它主要在等待客户端请求下一批数据(通常要格式化最后一批数据以供显示并做好显示工作)。
当大多数人谈论长时间运行的查询时,他们谈论的是 Oracle 正在处理的没有等待客户端提取数据的相对较长时间的查询。

酷炫的解释,Justin! - Maheswaran Ravisankar
非常感谢您的回复。这非常有帮助。 - user3524242
嗨Justin,再次感谢您的回复和解释Oracle如何处理select * from查询。我有一个问题是为什么v $ session显示last_call_et为零? - user3524242
@user3524242 - 因为每次客户端调用数据库并要求其执行工作时,last_call_et都会被重置,因为这些都是对数据库的单独调用。我更新了我的答案,以使其更加明确。 - Justin Cave

0

您可以使用以下脚本查找长时间运行的查询:

select * from
(
  select
     opname,
     start_time,
     target,
     sofar,
     totalwork,
     units,
     elapsed_seconds,
     message
   from
        v$session_longops
  order by start_time desc
)
where rownum <=1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接