导读:本期聚焦于书生创作的《如何使用Oracle SQL Monitor实现SQL语句的实时性能监控?》,敬请观看详情。一条SQL在数据库里跑了几个小时,到底慢在哪一步?DBA在排查时最需要的就是能看到SQL执行过程中的真实细节。Oracle SQL Monitor正是为此而生,它基于Oracle 11g引入的实时SQL监控特性,能够在SQL运行的同时采集每一步操作的执行统计信息,包括实际行数、耗时、内存与临时表空间占用等。本文将围绕SQL Monitor的触发条件、常用查看方式展开讲解,介绍通过SQL Monitoring明细页面、报告以及DBMS_TF等途径获取监控数据的完整流程,对比V$SQL_MONITOR视图的核心字段含义,并给出结合执行计划偏差分析的调优思路,帮助读者快速定位慢SQL的真实瓶颈,摆脱只看估算执行计划的盲区。

做Oracle性能优化的人几乎都遇到过这样的场景:一条SQL已经跑了几个小时,AWR报告里能看到它的总耗时,却无法知道它当前执行到哪一步、每一步处理了多少行、消耗了多少临时表空间。传统的执行计划只给出优化器的估算值,而估算与真实执行之间往往存在巨大偏差,这种偏差恰恰是性能问题的根源。Oracle SQL Monitor正是为了解决这个痛点而设计的工具,它可以对正在运行和刚刚结束的SQL进行实时级别的细粒度监控,把每一步操作的真实执行统计呈现出来。

如何使用Oracle SQL Monitor实现SQL语句的实时性能监控?

SQL Monitor的触发条件与底层机制

实时SQL监控是Oracle 11g企业版随Real Application Testing选件引入的特性,后来在19c中被并入Database In-Memory选件的一部分能力描述,但核心功能一直保持稳定。它并非对所有SQL都生效,而是有明确的触发条件,理解这些条件是使用它的第一步。

第一种触发方式是并行执行的SQL。只要一条SQL使用了并行,Oracle就会自动将其纳入监控范围,无需任何手工干预。第二种是单次执行消耗超过5秒CPU时间或IO时间的SQL,这类SQL通常被认为是耗资源的,数据库会自动开启监控。除此之外,用户也可以通过在SQL文本中加入monitor提示强制开启,或者使用no_monitor提示显式关闭。

-- 强制开启监控
SELECT /*+ MONITOR */ COUNT(*) FROM big_table WHERE create_date > SYSDATE - 30;

-- 强制关闭监控
SELECT /*+ NO_MONITOR */ COUNT(*) FROM small_table;

监控数据被记录在SGA中的一块循环使用的内存区域里,目标占用约为SGA的百分之五。当区域被写满时,最旧的监控记录会被清除。每条记录每隔一秒刷新一次统计信息,因此能看到接近实时的执行状态。监控记录默认保留一分钟,如果SQL执行结束后的记录被后续查询访问过,保留时间会延长,这也是为什么有时需要及时生成报告的原因。相关参数可以通过V$SQL_MONITORDBMS_SQLTUNE.REPORT_SQL_MONITOR配合管理。

三种常用的查看方式与核心视图

最常用的入口是V$SQL_MONITOR视图,它记录了每条被监控SQL的关键信息。其中最重要的几个字段需要熟练掌握:STATUS表示执行状态,QUEUED表示排队中,EXECUTING表示正在执行,DONE表示已完成;ELAPSED_TIME是累计耗时;CPU_TIMEIO_TIME分别对应处理器与IO消耗;PROCESS_NAME可以区分前台进程、并行从属进程或后台作业进程。

-- 查看当前正在执行的监控SQL
SELECT sql_id, status, username, elapsed_time/1000000 AS elapsed_sec,
       cpu_time/1000000 AS cpu_sec, buffer_gets, disk_reads
FROM   v$sql_monitor
WHERE  status = 'EXECUTING'
ORDER  BY elapsed_time DESC;

第二个入口是SQL Monitoring明细页面。在SQL Developer或Enterprise Manager Cloud Control中找到对应的SQL,进入其监控页面后,可以看到可视化的计划树,每个步骤标注了实际行数、估算行数和耗时占比,偏差巨大的步骤会用醒目的方式提示。第三个入口是纯文本报告,通过DBMS_SQLTUNE.REPORT_SQL_MONITOR函数生成,适合在没有图形界面的生产环境中使用。

-- 生成最近一次监控的文本报告
SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 200
SET PAGESIZE 0
SET HEADING OFF
SPOOL /tmp/monitor_report.txt
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
         type         => 'TEXT',
         report_level => 'ALL')
FROM   dual;
SPOOL OFF

type参数除了TEXT还支持HTML和XML。HTML格式的报告包含交互式的活动图和并行执行细节,是发给开发人员分析的最佳载体。如果需要监控一条SQL的多次执行汇总,可以改用REPORT_SQL_MONITOR_LIST函数。另外,活动会话历史视图V$ACTIVE_SESSION_HISTORY与SQL Monitor的detail部分数据来源一致,两者交叉验证能进一步确认瓶颈所在。

结合估算偏差做SQL调优分析

拿到监控报告后,调优的核心工作是比较估算行数与实际行数的差异。优化器基于统计信息做出估算,一旦统计信息过期、数据分布倾斜或存在复杂的谓词组合,估算就可能严重偏离实际,从而选择了错误的连接方式或访问路径。

典型的例子是嵌套循环连接:如果优化器估算内表只返回十行,会选择嵌套循环,但实际返回了一千万行,执行时就会表现为大量的逻辑读和超长耗时。在监控报告的计划树中,这类步骤的估算行数与实际行数旁边通常会有明显的偏差标记,耗时的横向条形图也会集中在一两个步骤上。定位到偏差步骤后,可以采取收集更精确的统计信息、改用动态采样、添加复合索引或改写SQL等手段。

对于并行执行的SQL,监控报告还提供了每个并行从属进程的工作量分布。如果发现某个从属进程承担了绝大部分工作而其他进程几乎空闲,说明数据倾斜导致并行度利用不充分,此时需要考虑对分区键做调整或使用分桶策略让数据分布更均匀。

使用SQL Monitor还需要注意几个细节。监控本身有轻微开销,但一秒一次的采样频率对绝大多数系统可以忽略。监控记录是易失的,实例重启后消失,因此排查历史问题应尽快生成报告,或者配合AWR、ASH做长期留存。对于执行时间很短但被频繁调用的SQL,SQL Monitor并不适合,此时应该转向V$SQL的累计统计并结合SQL概要数据分析。掌握这些边界条件,SQL Monitor才能真正成为定位慢SQL的利器。

Oracle SQL MonitorSQL性能监控Oracle调优修改时间:2026-09-13 03:12:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。