我们的文章会在微信公众号IT民工的龙马人生和博客网站 ( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
相信每一个Oracle DBA都对Oracle SQLHC脚本不陌生,因为在日常的Oracle数据库运维与性能优化工作中,SQL语句的执行效率始终是核心关注点之一。对于复杂的 SQL,DBA往往需要收集执行计划、统计信息、参数配置等多方面的数据,才能准确分析问题。为了帮助DBA系统化地诊断SQL性能瓶颈,Oracle提供了SQLHC(SQL Health Check) 工具。
SQLHC是由 Oracle Support 提供的一款诊断脚本,可以针对单条 SQL 语句进行全面的健康检查。它的主要目标是快速收集与SQL优化相关的各种信息,并生成详细的报告,帮助DBA或Oracle支持工程师分析性能问题。该工具以PL/SQL脚本的形式提供,下载后只需在数据库中以SYSDBA身份执行,即可生成分析结果。
SQLHC的工作原理是读取指定SQL的SQL_ID,随后从数据字典、AWR、CBO(优化器)统计信息中提取相关信息。生成的报告通常包括以下几个部分:
1. **SQL概览:**显示SQL文本、SQL_ID、解析用户、执行次数等基本信息。
2. **执行计划:**列出当前优化器选择的执行路径,并提供历史执行计划对比。
3. **对象与统计信息:**检查相关表、索引的统计信息是否存在偏差,是否需要更新。
4. **初始化参数:**列出影响优化器行为的关键参数,帮助确认是否存在非默认配置。
5. **诊断结论与建议:**在报告中总结潜在的问题点,并给出优化方向,如增加索引、收集统计信息或调整参数。
使用 SQLHC 的好处在于:
• **标准化诊断:**避免人工收集信息不完整,确保SQL诊断有统一框架。
• **快速定位问题:**通过一份报告集中呈现所有相关信息,节省大量排查时间。
• **支持远程协作:**报告可以直接提供给 Oracle Support,便于快速响应 SR。
• **非侵入性:**不会修改数据库对象,有大量的INSERT操作,仅做信息收集。
虽然SQLHC有这么的功能,但是做为一名接近20年的DBA来说,我可以说从来没有在生产环境中用过SQLHC的脚本,主要有如下的一些原因:
1.执行效率低: SQLHC中很多脚本其实没有做固定,在一些海量数据库环境中常常会出现性能问题,导致收集信息的执行效率低。
2.很多无效的信息: SQLHC中有很多跟自动调优相关的信息,这部分信息对于没有基础的DBA来说有一定的作用,但是对于有一定经验的DBA来说,真的没有太多价值。
3.HTML格式: SQLHC生成的文件是html格式,收集完成后需要下载到本地查看,这个对于生产上做优化来说,有些时候效率太低了,能下载到本地,打开html文件,很可能几分钟就没有了,有些时候黄花菜都晾了;另外有很多客户没有开通下载的权限。
4.收集信息不全: SQLHC收集的信息还是不全,无法快速的覆盖SQL分析所需要的信息,比如自动替换SQL中绑定变量的值、访问对象的大小等等。
SQL10的介绍
简单介绍
下面就是今天的重点SQL10脚本,此脚本是我自己在日常工作中使用频率排名第二的脚本,他的功能类似于SQLHC脚本,但是很好的解决了上面提到的SQLHC脚本的一些局限性,并且整个脚本不存在任何对象、也不执行任何INSERT语句,做到了对生产环境完全无侵入。
此脚本已经在行业内最少被几百个DBA所使用,使用系统覆盖了各行各业。就我自己而言,最少也是上千套数据库里面执行过此脚本,可以达到秒级别的输出信息。
适用版本与特性开关
- 支持 10.2+,对 11g/12c+ 使用条件开关:
_VERSION_10/_11/_12
:按v$version
结果控制不同版本分支(如 SQL Monitor、ASH 处理)。_SQL_MONITOR
:默认关闭;手动开启后生成 SQL Monitor 报告。
- 支持 CDB 环境(当前设计在 PDB 中对单一
sql_id
使用)。 - 重要依赖
- 视图与包:
v$sql*
、v$active_session_history
、dba_hist_*
、dba_*
、DBMS_XPLAN
、DBMS_SQLTUNE
、DBMS_SPACE_ADMIN
- 需具备相应查询权限;AWR/Monitor 涉及诊断包授权。
- 视图与包:
快速使用
- 在 SQL*Plus 中执行脚本并传入
sqlid
:
@sql10.sql
输入sqlid信息即可
- 如需开启 SQL Monitor(11gR2+),在脚本顶部设置:
define _SQL_MONITOR = " "
- 结果会自动
spool
到文件,命名规则:
18081072613_<HOST>_<INSTANCE>_<sqlid>_<yyyymmddhh24>_htz.txt
目前已经实现的功能
- LITERAL SQL:从
v$sql_bind_capture
取绑定,自动将绑定值替换回 SQL,复原一条可读的“字面量 SQL”,便于人工审阅与重放。 - 执行计划(Cursor):用
dbms_xplan.display_cursor
输出实际执行计划。 - ASH 计划行热点:统计各 plan line 的等待事件占比,标注到执行计划右侧,直击瓶颈步骤。
- SQL Monitor(可选):
DBMS_SQLTUNE.report_sql_monitor
输出运行态报告。 - SQL 统计:按“每次执行”维度输出 CPU/Elapsed/IO/Buffer Gets/Rows/Fetches 及各类等待时间,单位智能换算(ms/s/m/h;K/W)。
- AWR 最近 5 天快照增量:展示不同时间窗口的执行增量与性能指标变化,辅助回溯问题时段。
- 等待事件直方:按
program/event/wait_class
维度聚合 ASH(最近 4 小时),识别端到端瓶颈。 - 对象尺寸:基于
v$sql_plan
与dba_hist_sql_plan
涉及对象,统计段大小(MB),标星标注“表主段”。 - 表与列统计:表属性、分区、估算大小、收集时间;列直方图、密度、空值、基数等,辅助判定统计信息质量。
- 索引状态/信息:无效/不可用分区;索引列与属性编码 UCPTDVS(唯一/压缩/分区/临时/可见性/段创建)
关键模块详解
1) LITERAL SQL(绑定值复原)
- 逻辑
- 读取
v$sql.sql_fulltext
- 遍历
v$sql_bind_capture
的name/position/datatype/value_string
- 规范化系统绑定名(如
:SYS_B_...
→:"SYS_B_..."
),基于类型用regexp_replace
替换成字面量值,NULL 特殊处理 - 输出
Schema:
与最终字面量 SQL
- 读取
- 价值
- 复盘 SQL 真正入参,便于重放与对比执行计划
- 冷热点 SQL 绑定嗅探、硬解析排查更直观
2) 实际执行计划(Cursor)
- 查询
v$sql
并用:
select t.*
from v$sql s, table(dbms_xplan.display_cursor(s.sql_id, s.child_number)) t
where s.sql_id = '&&sqlid';
- 多 child 计划并列展示,便于对比 plan hash、outline 差异。
3) PLAN STAT FROM ASH(执行计划热点行标注)
- 对 ASH 中同一
sql_id
的sql_plan_line_id
聚合等待事件与占比 - 再与
dbms_xplan.display_cursor
输出行(通过行号正则)关联 - 在每行计划右侧追加“主要等待(次数)(占比%)”,例如:
db file sequential read(1200)(65.4%)
- 仅 11g+ 分支执行,指向性极强的热点定位。
4) SQL Monitor(可选)
- 通过
DBMS_SQLTUNE.report_sql_monitor(sql_id=>'&&sqlid', type=>'TEXT', report_level=>'NONE+PLAN+ACTIVITY-...')
输出文本版 Monitor,用于长跑 SQL 的实时画像。
5) SQL STATS(v$sqlstats / v$sql / v$sqlarea)
- 面向“每次执行”的衡量:
CPU/Elapsed/IO/Buffer Gets/Rows/Fetches
等 - 单位智能化:
- 数值:
<1000
原值;K
=千,W
=万 - 时间:自动换算到
ms/s/m/h
- 数值:
- 同时列出
plan_hash_value/child_number/schema/first_last_load_time/sql_profile
,利于判断绑定嗅探与软硬解析行为。
6) AWR 时间序列(最近 5 天)
dba_hist_sqlstat
联dba_hist_snapshot
,输出executions_delta
及每次执行的增量指标- 用于确认“何时变慢/变多/变重”,辅助定位变更窗口或数据倾斜窗口。
7) SQL WAIT HIST(ASH)
- 将 ASH 中
SESSION_STATE
→CPU/BCPU 归一化,与event/wait_class/program
聚合 - 统计最近 4 小时(可改窗口),识别前台/后台主要等待来源。
8) OBJECT SIZE(段空间)
- 以
v$sql_plan
+dba_hist_sql_plan
涉及对象为全集,汇总段大小(MB) - 通过内部数据字典表(
sys.user$ / obj$ / seg$ / ts$ / file$ ...
)与DBMS_SPACE_ADMIN.segment_number_blocks
计算更准确的块数 - 为“是否需要分区/索引重建/表压缩/分区裁剪”等提供依据。
9) TABLES / TABLE COLUMNS(统计健诊)
- 表层面:
logging/temporary/buffer_pool/degree/partitioned/num_rows/blocks/上次分析时间
- 列层面:
data_type(length)/nullable/density/num_distinct/buckets/histogram/avg_col_len/sample_size/last_analyzed
- 帮助判定:是否缺统计、直方图是否合适、列选择度与连接基数是否可靠。
10) INDEX STATUS / INDEX INFO(UCPTDVS)
- 无效索引与不可用分区子分区一览,优先修复对象健康。
UCPTDVS
编码含义:- U/N:Unique/NonUnique
- E/N:Compression Enabled/Disabled
- Y/N:Partitioned Yes/No
- Y/N:Temporary Yes/No
- V/I:Visibility Visible/Invisible(11g+)
- Y/N:Segment Created Yes/No(11g+)
- 同时输出索引列与顺序,辅助判断是否需覆盖/重排。
11) PARTITION INDEX / INDEX STATS
- 索引分区键列、分区与子分区类型/数量、本地/全局、对齐方式(
LOCALITY/ALIGNMENT
) BLEVEL/LEAF_BLOCKS/DISTINCT_KEYS/CLUSTERING_FACTOR
等,评估访问成本与扫描选择性。
12) PARTITION TABLE 与分区清单
- 分区键、类型、数量与键列顺序
- 每个分区的
HIGH_VALUE/NUM_ROWS/BLOCKS/大小/EMPTY_BLOCKS/最后分析时间/压缩
,判断冷热分布与统计新鲜度,指导分区维护与裁剪策略。
脚本的获取
关注公众号,后台回复“脚本”二字。
——————作者介绍———————–
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)
DBA必备脚本:比SQLHC好用100倍的SQL性能优化脚本:等您坐沙发呢!