当前位置: 首页 > 调优 > 正文

我们的文章会在微信公众号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_historydba_hist_*dba_*DBMS_XPLANDBMS_SQLTUNEDBMS_SPACE_ADMIN
    • 需具备相应查询权限;AWR/Monitor 涉及诊断包授权。

快速使用

  1. 在 SQL*Plus 中执行脚本并传入 sqlid
@sql10.sql
输入sqlid信息即可
  1. 如需开启 SQL Monitor(11gR2+),在脚本顶部设置:
define _SQL_MONITOR = "  "
  1. 结果会自动 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_plandba_hist_sql_plan 涉及对象,统计段大小(MB),标星标注“表主段”。
  • 表与列统计:表属性、分区、估算大小、收集时间;列直方图、密度、空值、基数等,辅助判定统计信息质量。
  • 索引状态/信息:无效/不可用分区;索引列与属性编码 UCPTDVS(唯一/压缩/分区/临时/可见性/段创建)

关键模块详解

1) LITERAL SQL(绑定值复原)

  • 逻辑
    • 读取 v$sql.sql_fulltext
    • 遍历 v$sql_bind_capturename/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_idsql_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_sqlstatdba_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性能优化脚本:等您坐沙发呢!

发表评论

gravatar

? razz sad evil ! smile oops grin eek shock ??? cool lol mad twisted roll wink idea arrow neutral cry mrgreen

快捷键:Ctrl+Enter