oracle无法按精确时间点回溯正在执行的sql,只能通过v$sql_monitor(含sql_exec_start,保留约1分钟)或awr中的dba_hist_active_sess_history(ash,每秒采样,需权限与快照支持)逼近查询;v$sql的first_load_time和last_active_time不可靠,因其分别表示硬解析时间和最后完成时间,且记录可能被内存淘汰。

Oracle 无法直接按“某个时间点”精确回溯正在执行的 SQL,因为 V$SQL、V$SESSION 等动态视图只反映当前内存状态,不保存历史快照。 你真正能查到的,是「当时仍在运行、且尚未结束、且未被从共享池淘汰」的语句 —— 这依赖于语句是否还在 V$SQL 中,以及是否在 V$SQL_MONITOR 或 AWR 中有留存记录。
查 V$SQL_MONITOR:唯一能接近“时间点”的实时监控入口
Oracle 11g+ 自动对满足条件的 SQL 启动 SQL 监控(如单次执行耗时 ≥5 秒、或启用并行),相关信息写入 V$SQL_MONITOR。该视图保留时间极短(通常 ≤1 分钟),但字段含实际开始时间:SQL_EXEC_START。
若你记得大概时间(比如 2026-07-27 19:35:22),可尝试:
SELECT sql_id, sql_text, status, sql_exec_start, elapsed_time/1000000 AS elapsed_s, cpu_time/1000000 AS cpu_s FROM v$sql_monitor WHERE sql_exec_start >= TIMESTAMP '2026-07-27 19:35:00' AND sql_exec_start
-
status = 'EXECUTING'表示当时确实在跑;DONE表示已结束但记录尚在 -
elapsed_time单位是微秒(注意除以 1000000 转秒) - 该视图不包含所有 SQL,仅限触发监控阈值的语句 —— 短查询、非并行、无资源争用的语句不会出现
- 如果目标时间已过 1–2 分钟,大概率查不到,
V$SQL_MONITOR记录已被自动清理
查 AWR 快照:唯一可靠的“过去式”溯源方式
AWR(Automatic Workload Repository)每小时默认采集一次快照(可配置为更密),其中 DBA_HIST_SQLSTAT 和 DBA_HIST_ACTIVE_SESS_HISTORY(ASH)才是你真正需要的历史依据。
要定位某时间点的活跃 SQL,优先查 ASH:
SELECT sql_id, sql_plan_hash_value, session_id, session_serial#, program, machine,
sample_time, event, p1text, p1, p2text, p2
FROM dba_hist_active_sess_history
WHERE sample_time >= TIMESTAMP '2026-07-27 19:35:00'
AND sample_time
-
sample_time是采样时刻(非 SQL 开始时间),但每秒最多 1 条记录,足够逼近“正在执行”状态 - 必须有相应 AWR 快照覆盖该时段,且用户有
SELECT_CATALOG_ROLE或DBA权限 - 若没开 ASH(极少见),或该时段未被采样到(如空闲会话占比高),则无数据
- 用
DBA_HIST_SQLSTAT只能看到聚合统计(如总执行次数、平均耗时),看不到具体某次执行的上下文
为什么 V$SQL 的 FIRST_LOAD_TIME / LAST_ACTIVE_TIME 不可靠?
这两个字段常被误当作“时间点依据”,但实际意义完全不同:
-
FIRST_LOAD_TIME是硬解析载入共享池的时间,不是执行开始时间;一条 SQL 可能被缓存数小时,之后被反复软解析执行 -
LAST_ACTIVE_TIME是最后一次执行完成的时间,不是执行中时间;它更新于语句结束时,且不保证精度(可能延迟几秒) - 即使你看到某条 SQL 的
LAST_ACTIVE_TIME接近目标时间,也无法确认它在那个时刻是否真在跑 —— 它可能刚结束,也可能根本没启动 - 更重要的是:
V$SQL记录随时可能因内存压力被老化淘汰,没有时间保底机制
真正能回答“那个时间点谁在跑什么”的,只有 ASH(带采样时间戳)或 SQL Monitor(带 SQL_EXEC_START)。其他视图全是间接推断,误差大、不可验证。如果你没开 AWR/ASH,或目标时间超出保留周期,那这个查询本质上就是无解的 —— Oracle 不记,你就查不到。











