v$active_session_history的核心价值在于每秒采样活跃会话,定时任务只要执行中且非空闲即被记录;应按实际运行时间过滤sample_time,结合module、session_state、in_hard_parse等字段定位性能瓶颈,并善用top_level_sql_id等关键字段分析调度链路。

直接查 v$active_session_history 里的定时任务会话
ASH 的核心价值在于它每秒采样一次活动会话,而定时任务(比如 DBMS_SCHEDULER 作业或 cron 触发的 SQL)只要在执行中、且处于非空闲等待状态,就会被记录。关键不是“它是不是定时任务”,而是“它执行时是否活跃”。
先确认你的定时任务大概在什么时间运行,再用 v$active_session_history 查那个窗口内的样本:
- 用
SAMPLE_TIME过滤时间范围,别只依赖SYSDATE - INTERVAL '10' MINUTE—— 如果任务是每天凌晨 2:15 执行,你得手动写SAMPLE_TIME BETWEEN TO_TIMESTAMP('2026-07-21 02:14:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2026-07-21 02:16:00', 'YYYY-MM-DD HH24:MI:SS') - 加
MODULE或ACTION过滤:很多调度框架(如 Oracle Scheduler、自定义 PL/SQL 包)会在执行前调用DBMS_APPLICATION_INFO.SET_MODULE,查MODULE列就能快速圈定目标会话 - 别漏掉
SESSION_STATE = 'ON CPU'或EVENT LIKE '%wait%'—— 定时任务慢,90% 是卡在 CPU 或某类等待上,不是“没记录”
用 dba_hist_active_sess_history 查历史周期性问题
dba_hist_active_sess_history 是磁盘持久化的 ASH 历史,每 10 秒存一次,适合查“昨天/上周同一时间又慢了”这类周期性问题。但它分辨率比内存视图低,不能替代实时诊断。
常见误操作是直接 SELECT * FROM dba_hist_active_sess_history WHERE SAMPLE_TIME > SYSDATE - 7 —— 这会扫全表,性能极差。正确做法:
- 先用
DBA_HIST_SNAPSHOT查出目标时间段对应的快照 ID 范围:SELECT MIN(SNAP_ID), MAX(SNAP_ID) FROM DBA_HIST_SNAPSHOT WHERE BEGIN_INTERVAL_TIME BETWEEN ... AND ... - 再用
SNAP_ID联查dba_hist_active_sess_history,避免全表扫描 - 如果任务固定在整点跑,可按
TO_CHAR(SAMPLE_TIME, 'HH24')分组统计COUNT(*),看某小时是否样本数突增 —— 这往往对应资源争用高峰
识别定时任务 SQL 的硬解析风暴
很多定时任务用拼接 SQL(比如 'SELECT * FROM t WHERE dt = ''' || v_date || ''''),导致每次执行都硬解析,in_hard_parse = 'Y' 会高频出现。这比慢查询本身更伤性能。
查这个现象最直接的 SQL 是:
SELECT in_parse, in_hard_parse, COUNT(*) cnt FROM v$active_session_history WHERE SAMPLE_TIME > SYSDATE - INTERVAL '30' MINUTE AND (in_parse = 'Y' OR in_hard_parse = 'Y') GROUP BY in_parse, in_hard_parse;
如果 in_hard_parse = 'Y' 占比超过 15%,基本可以断定是绑定变量缺失。此时再结合 SQL_ID 和 SQL_CHILD_NUMBER 查具体语句 —— 同一 SQL_ID 下多个子游标,说明执行计划不稳定,不能只看 V$SQL.SQL_TEXT,得用 V$SQL_SHARED_CURSOR 看原因。
ASH 报告里容易被忽略的三个字段
生成 ASH 报告(@?/rdbms/admin/ashrpt.sql)后,很多人只盯着 Top SQL 和 Top Events,但以下三个字段对定时任务特别关键:
-
TOP_LEVEL_SQL_ID:定时任务里常嵌套调用存储过程,SQL_ID可能是子过程里的,而TOP_LEVEL_SQL_ID指向最外层调度语句,这才是真正触发点 -
PLSQL_ENTRY_OBJECT_ID+PLSQL_ENTRY_SUBPROGRAM_ID:能定位到具体是哪个包/过程在耗资源,比猜MODULE更准 -
CONSUMER_GROUP_ID:如果用了资源管理器(Resource Manager),定时任务可能被分配到低优先级组,CONSUMER_GROUP_ID对应DBA_RSRC_CONSUMER_GROUPS就能验证是否被限流
这些字段默认不显示在文本报告里,需要在生成报告时选 “Advanced” 模式,或直接查 v$active_session_history 加字段过滤 —— 内存视图里它们一直存在,只是报告模板没展开。











