sql monitor未记录慢sql主因是未达监控阈值:仅监控并行sql或单次执行耗时≥5秒的语句,与awr保留策略无关。
sql monitor 没记录慢 sql,和 awr 保留策略基本无关——它俩压根不是一回事。awr 是定时采样、汇总、落盘的“历史快照”,而 sql monitor 是运行时内存中实时跟踪单条 sql 执行过程的诊断工具。你查不到某条慢 sql 的 monitor 记录,大概率是它根本没被监控,而不是“数据被 awr 清掉了”。
SQL Monitor 不显示慢 SQL 的真实原因
Oracle 默认只监控两类语句:并行执行的 SQL,或单次执行消耗 CPU + I/O 时间 ≥ 5 秒的语句。注意:是“单次执行”,不是“平均耗时”,也不是“总耗时”。很多业务 SQL 虽然慢,但每次只跑 2–3 秒,或者因并发高被拆成多个短执行,就直接被过滤掉了。
- 检查是否真触发了监控:查
V$SQL_MONITOR,用SQL_ID和准确的LAST_REFRESH_TIME范围过滤,别只看STATUS = 'DONE',有些已老化到V$SQL_PLAN_MONITOR - 确认执行时间是否达标:用
V$SQL查该 SQL 的ELAPSED_TIME / EXECUTIONS,如果平均值 - 第三方应用无法加
/*+ MONITOR */?可用系统级事件强制:执行ALTER SYSTEM SET EVENTS 'sql_monitor [sql: abc123def456] force=true',但仅限临时排障,别长期开着
为什么改 AWR retention 对 Monitor 没用
AWR 快照里存的是聚合后的性能指标(比如每秒逻辑读、CPU 时间总和),不是 SQL 的逐行执行轨迹。即使你把 retention 从 8 天调到 30 天,DBA_HIST_SQLSTAT 里也只保留每个快照周期内 SQL 的统计增量(ELAPSED_TIME_DELTA),不存执行计划树、绑定变量值、IO 分布这些 Monitor 独有的细节。
-
DBA_HIST_SQLSTAT只能告诉你“这条 SQL 在第 12345 号快照里跑了 120 秒”,但不知道它卡在哪一步、等了什么锁、用了几个 buffer pool - Monitor 数据默认只在内存保留几分钟(受
_sqlmon_max_plan和共享池压力影响),AWR 根本不接管这部分内容 - 想靠 AWR 报告反推 Monitor 信息?不行。AWR 报告里的 “SQL ordered by Elapsed Time” 是从
DBA_HIST_SQLSTAT算出来的,和 Monitor 无任何数据链路
真正该调的两个参数:_sqlmon_threshold 和 _sqlmon_max_plan
如果你确定某类 SQL 总是略低于 5 秒阈值但实际影响业务,可以下调监控门槛。但必须清楚代价:
- 设
_sqlmon_threshold = 2(单位秒):更多 SQL 进入 Monitor,但V$SQL_MONITOR占用内存翻倍,老化更快,可能刚查就没了 - 设
_sqlmon_max_plan = 50(默认是20 * CPU_COUNT):允许更多并发监控,但会挤占 shared pool,可能影响 cursor cache 命中率 - 这两个都是下划线参数,不能用
ALTER SYSTEM SCOPE=BOTH直接改;需加scope=spfile并重启,且只应在明确问题场景下调整
最常被忽略的一点:SQL Monitor 记录是否还在,和数据库当前负载强相关。哪怕你设了 _sqlmon_threshold = 1,当 shared pool 吃紧或并发监控数超限时,新执行的 SQL 依然会被跳过——它优先保命,不保记录。排查前先看 V$SQL_MONITOR 的 STATUS 列有没有大量 EXECUTING 卡住,再看 V$SGASTAT 里 sql monitor 相关内存是否接近上限。











