SQL Monitor是Oracle官方提供的自动监控符合特定条件的SQL,用于收集执行时的细节信息的监控工具,常用于SQL调优和系统性能监控。
Oracle 11g中,当SQL满足以下条件之一就会被SQL Monitor捕获到,监控数据被记录在v$sql_monitor视图中,
(1) 当SQL并行执行时,会立即被实时监控到。
(2) 当SQL单进程运行时,如果消耗超过5秒的CPU或I/O时间,会监控到。
(3) 使用/*+ monitor */提示的SQL语句。
另外一个前提,就是以下两个参数的设置,
(1) statistics_level级别必须是TYPICAL或者ALL。
(2) control_management_pack_access设置为'DIAGNOSTIC+TUNING'。
SQL Monitor在Oracle企业版数据库中是免费使用的,打开SQL Monitor Report有两种形式,一个就是通过Oracle EM,中文名称是“SQL监控”,

另外一种获得SQL Monitor Report的形式就是通过dbms_sqltune包,这可能是我们经常用到的,一个原因是我们未必能使用图形界面,尤其是生产环境,端口都是禁用的,另外一个原因,就是我们能在监控脚本中调用dbms_sqltune,便于编写我们的监控逻辑。
我们尝试通过dbms_sqltune看下这个SQL Monitor Report。
(1) 确认参数
SQL> show parameter statistics_levelNAME TYPE VALUE------------------------------------ ----------- ------------------------------statistics_level string TYPICALSQL> show parameter control_management_pack_access;NAME TYPE VALUE------------------------------------ ----------- ------------------------------control_management_pack_access string DIAGNOSTIC+TUNING
(2) 确定要监控的SQL ID
其实就是确定什么样的SQL会记录到v$sql_monitor视图中,这里我们采用hint,让SQL进入v$sql_monitor,
SQL> select /*+ monitor */ type, count(*) from v$lock group by type;TY COUNT(*)-- ----------CF 1KT 3RD 1KD 1XR 1RT 1AE 7TS 2RS 1TO 3MR 14
可从v$sql或者v$sql_monitor找到这条SQL的ID,
SQL> select sql_id,sql_text from v$sql_monitor where sql_text like '%v$lock%';SQL_ID SQL_TEXT------------------------------------------------------------------------------02qa4khbuqv92 select /*+ monitor */ type, count(*) from v$lock group by type
(3) dbms_sqltune
通过设置set,格式化输出,还可以选择spool,将输出打印到本地文件中,其中dbms_sqltune.report_sql_monitor可以指定报告的格式,包括'TEXT'、'HTML'、'XML' 、'ACTIVE'(只在11g R2以后才支持),
SQL> set long 1000000SQL> set longchunksize 100000SQL> set linesize 1000SQL> set pagesize 0SQL> set trim onSQL> set trimspool onSQL> set echo offSQL> set feedback offSQL> spool report_sql_monitor.txtSQL> select dbms_sqltune.report_sql_monitor(sql_id=>'02qa4khbuqv92', type=>'TEXT', report_level=>'ALL') as report from dual;SQL Monitoring ReportSQL Text------------------------------select /*+ monitor */ type, count(*) from v$lock group by typeGlobal Information------------------------------Status : DONE (ALL ROWS)Instance ID : 1Session : SYS (1:38345)SQL ID : 02qa4khbuqv92SQL Execution ID : 16777216Execution Started : 02/05/2022 15:20:01First Refresh Time : 02/05/2022 15:20:01Last Refresh Time : 02/05/2022 15:20:01Duration : .027419sModule/Action : sqlplus@centos (TNS V1-V3)/-Service : SYS$USERSProgram : sqlplus@centos (TNS V1-V3)Fetch Calls : 2Global Stats========================================| Elapsed | Cpu | Other | Fetch || Time(s) | Time(s) | Waits(s) | Calls |========================================| 0.03 | 0.01 | 0.02 | 2 |========================================SQL Plan Monitoring Details (Plan Hash Value=3191625931)==============================================================================================================================================| Id | Operation | Name | Rows | Cost | Time | Start | Execs | Rows | Mem | Activity | Activity Detail || | | | (Estim) | | Active(s) | Active | | (Actual) | (Max) | (%) | (# samples) |==============================================================================================================================================| 0 | SELECT STATEMENT | | | | 1 | +0 | 1 | 11 | . | | || 1 | HASH GROUP BY | | 29 | 2 | 1 | +0 | 1 | 11 | 1MB | | || 2 | HASH JOIN | | 5576 | 1 | 1 | +0 | 1 | 35 | 1MB | | || 3 | HASH JOIN | | 242 | 1 | 1 | +0 | 1 | 35 | 2MB | | || 4 | VIEW | GV$_LOCK | 242 | 1 | 1 | +0 | 1 | 37 | . | | || 5 | UNION-ALL | | | | 1 | +0 | 1 | 37 | . | | || 6 | FILTER | | | | 1 | +0 | 1 | 37 | . | | || 7 | VIEW | GV$_LOCK1 | 234 | 1 | 1 | +0 | 1 | 37 | . | | || 8 | UNION-ALL | | | | 1 | +0 | 1 | 37 | . | | || 9 | FIXED TABLE FULL | X$KDNSSF | 1 | | | | 1 | | . | | || 10 | FIXED TABLE FULL | X$KSQEQ | 233 | 1 | 1 | +0 | 1 | 37 | . | | || 11 | FIXED TABLE FULL | X$KTADM | 1 | | | | 1 | | . | | || 12 | FIXED TABLE FULL | X$KTATRFIL | 1 | | | | 1 | | . | | || 13 | FIXED TABLE FULL | X$KTATRFSL | 1 | | | | 1 | | . | | || 14 | FIXED TABLE FULL | X$KTATL | 1 | | | | 1 | | . | | || 15 | FIXED TABLE FULL | X$KTSTUSC | 1 | | | | 1 | | . | | || 16 | FIXED TABLE FULL | X$KTSTUSS | 1 | | | | 1 | | . | | || 17 | FIXED TABLE FULL | X$KTSTUSG | 1 | | | | 1 | | . | | || 18 | FIXED TABLE FULL | X$KTCXB | 1 | | | | 1 | | . | | || 19 | FIXED TABLE FULL | X$KSUSE | 472 | | 1 | +0 | 1 | 472 | . | | || 20 | FIXED TABLE FULL | X$KSQRS | 2304 | | 1 | +0 | 1 | 2304 | . | | |==============================================================================================================================================SQL> spool off
如果选择HTML格式的,
select dbms_sqltune.report_sql_monitor(sql_id=>'02qa4khbuqv92', type=>'HTML', report_level=>'ALL') as report from dual;
就得到了HTML的SQL Monitor Report,

结合SQL Monitor Report,我们就可以关注其中存在的一些问题,例如通常会根据最右边CPU和wait的activity,找到SQL执行计划中资源消耗较高的步骤。然后看下Oracle估算的返回行数和实际的返回行数是否相差很大,如果估算的行数和实际的行数相差不大,至少表明目前对应数据库对象上的统计信息是准确的,否则就可能存在统计信息不准的问题。还可以关注SQL的筛选条件,判断是否使用了正确的索引等优化手段。
可以说SQL Monitor是个有效采集信息便于诊断SQL性能问题的一个“可视化”工具,但具体的问题和原因,还是要具体分析,看到的,未必是真实的,就像破案一样,这可能才是调优的乐趣所在。
近期更新的文章:
《关于数据治理的读书笔记 - 数据治理、数据管理和数据管控的理解》
文章分类和索引:




