You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle查询活跃运行SQL却返回已完成语句的原因排查

为何查询活跃SQL会返回已完成的语句?

核心原因分析

  • ACTIVE状态的误解:Oracle中gv$session.status = 'ACTIVE'仅表示会话未处于空闲(IDLE)状态,并非等同于SQL正在执行。比如SQL Developer中,会话执行完SQL后不会立即切换为IDLE,可能保持ACTIVE状态等待下一次操作,此时sql_id仍保留上一次执行的SQL标识。
  • 共享池SQL的残留:gv$sqlarea存储的是共享池中的SQL元数据,只要SQL未被老化出共享池,就会一直存在。即使会话中对应的SQL已经执行完成,gv$session.sql_id仍会指向这条已完成的SQL,导致关联后被查询出来。
  • sql_exec_start未实时清空:该字段记录的是SQL执行的起始时间,SQL完成后不会被立即重置,因此排序时这些已完成的SQL仍会被纳入结果。

改进后的查询语句

要精准筛选正在运行的活跃SQL,可以加入更多判断条件,确保会话确实在执行SQL:

SELECT a.sql_id,
       sql_exec_start,
       a.inst_id,
       a.sid,
       a.serial#,
       a.username,
       b.sql_text
FROM gv$session a
INNER JOIN gv$sqlarea b
ON a.sql_id     = b.sql_id
AND a.inst_id = b.inst_id
WHERE a.status    = 'ACTIVE'
AND a.type      = 'USER'
AND a.sql_id IS NOT NULL
-- 过滤会话状态为执行中或等待SQL相关资源
AND a.state IN ('EXECUTING', 'WAITING')
-- 关联SQL执行视图,确保SQL处于活跃执行状态
AND EXISTS (
    SELECT 1 
    FROM gv$sql_execution e
    WHERE e.inst_id = a.inst_id
      AND e.sql_id = a.sql_id
      AND e.sql_exec_id = a.sql_exec_id
      AND e.status = 'EXECUTING'
)
ORDER BY sql_exec_start ASC;

补充说明

如果需要监控长运行SQL,也可以结合gv$session_longops视图,该视图专门记录运行时间超过6秒的SQL执行情况,能更精准定位正在运行的耗时语句。

内容的提问来源于stack exchange,提问作者Javi Torre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:11:03