先上sql语句,在详细讲解这条sql的作用,下面这条sql,在工作中经常使用。
select to_char (b.END_INTERVAL_TIME,'yyyymmddhh24mi') shijian, a.plan_hash_value plan_hash, sum (a.EXECUTIONS_DELTA) execu_d, sum (a.BUFFER_GETS_DELTA ) bg_d, sum (a.DISK_READS_DELTA ) dr_d, sum (a.ELAPSED_TIME_DELTA/1000000) et_d, sum (a.CPU_TIME_DELTA/1000000) ct_d, sum (IOWAIT_DELTA/1000000) io_time, sum (CLWAIT_DELTA/1000000) clus_time, sum (APWAIT_DELTA/1000000) ap_time, sum (ccwait_delta/1000000) cc_time, decode (sum (a.EXECUTIONS_DELTA),0,sum (a.ELAPSED_TIME_DELTA/1000000),sum (a.ELAPSED_TIME_DELTA/1000000)/sum (a.EXECUTIONS_DELTA)) et_onetime from dba_hist_sqlstat a, dba_hist_snapshot b where a.SNAP_ID =b.SNAP_ID and a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.sql_id='&sql_id' and b.END_INTERVAL_TIME > sysdate - 6 group by to_char(b.END_INTERVAL_TIME,'yyyymmddhh24mi'),a.plan_hash_value order by 1;
核心用途:针对指定 SQL_ID,从 AWR 历史性能视图,按 AWR 采样时间 + 执行计划哈希值,统计近 6 天内该 SQL 的分段性能指标,用于追踪这条 SQL 性能随时间变化、执行计划是否漂移、资源消耗变化。
数据源:
dba_hist_sqlstat(AWR SQL 统计增量数据) +dba_hist_snapshot(AWR 采样快照时间) 适用:Oracle 10g/11g/12c/19c(传统 AWR 架构,CDB 环境需要适配) 前提:数据库 AWR 自动采样正常开启,AWR 保留时长≥6 天,账号有SELECT_CATALOG_ROLE权限
SNAP_ID:快照编号INSTANCE_NUMBER:RAC 实例号END_INTERVAL_TIME:该快照
采集结束时间(这个时间代表【上一个 snap ~ 当前 snap】这段周期的统计数据)重点:
xxx_DELTA= 两个 snapshot 间隔内新增的指标,不是自实例启动以来总和 。每条记录代表:在
snap N → snap N+1这个时间段内,该 sql_id+plan_hash_value 产生的资源消耗
| 字段 | 含义 | 单位 |
|---|---|---|
| EXECUTIONS_DELTA | 间隔内总执行次数 | 次 |
| BUFFER_GETS_DELTA | 逻辑读(buffer gets)增量 | 块 |
| DISK_READS_DELTA | 物理读增量 | 块 |
| ELAPSED_TIME_DELTA | 总耗时 | 微秒(μs) |
| CPU_TIME_DELTA | CPU 耗时 | 微秒(μs) |
| IOWAIT_DELTA | IO 等待时间 | 微秒(μs) |
| CLWAIT_DELTA | Cluster 集群等待时间(RAC 特有的全局缓存等待,gc 类等待) | 微秒(μs) |
| APWAIT_DELTA | Application 应用等待(锁、行锁、enqueue 等) | 微秒(μs) |
| CCWAIT_DELTA | Concurrency 并发等待(latch、mutex 等内部并发资源争抢) | 微秒(μs) |
to_char(b.END_INTERVAL_TIME,'yyyymmddhh24mi') shijian
AWR 快照结束时间,
代表这一行指标归属的时间窗口,格式
yyyyMMddHHmi(年月日时分)
a.plan_hash_value plan_hash
SQL 执行计划哈希值; 同一个 SQL_ID 如果 plan_hash_value 变了 = 执行计划漂移(这条 SQL 核心监控点)
sum(a.EXECUTIONS_DELTA) execu_d --窗口内总执行次数 sum(a.BUFFER_GETS_DELTA ) bg_d --窗口内总逻辑读 sum(a.DISK_READS_DELTA ) dr_d --窗口内总物理读
窗口内总执行次数、总逻辑读、总物理读
sum(a.ELAPSED_TIME_DELTA/1000000) et_d --总耗时 sum(a.CPU_TIME_DELTA/1000000) ct_d --CPU 时间 sum(IOWAIT_DELTA/1000000) io_time --IO 等待 sum(CLWAIT_DELTA/1000000) clus_time --RAC 集群等待 sum(APWAIT_DELTA/1000000) ap_time --应用锁等待 sum(ccwait_delta/1000000) cc_time --并发 latch 等待
/1000000:微秒 → 秒et_d:总耗时;ct_d:CPU 时间;io_time:IO 等待;clus_time:RAC 集群等待;ap_time:应用锁等待;cc_time:并发 latch 等待
decode(sum(a.EXECUTIONS_DELTA),0,sum(a.ELAPSED_TIME_DELTA/1000000),sum(a.ELAPSED_TIME_DELTA/1000000)/sum(a.EXECUTIONS_DELTA)) et_onetime
单次平均执行耗时(秒)
a.SNAP_ID =b.SNAP_ID and a.INSTANCE_NUMBER=b.INSTANCE_NUMBER
关联快照和 SQL 统计,RAC 环境必须匹配实例号,否则数据错乱
a.sql_id='&sql_id'
输入目标 SQL_ID,变量替换
b.END_INTERVAL_TIME > sysdate - 6
只查询 最近 6 天的 AWR 快照数据
group by to_char(b.END_INTERVAL_TIME,'yyyymmddhh24mi'),a.plan_hash_value order by 1;
核心逻辑:同一时间窗口下,如果出现多个不同 plan_hash_value 会拆成多行。
直接肉眼就能识别: 什么时间点 SQL 换了执行计划,同时伴随单次耗时暴涨 / 逻辑读飙升
输出结果里,如果
同一个 sql_id,同一个时间段前后 plan_hash_value 发生变化,同时
et_onetime、
bg_d暴涨 → 实锤执行计划变更导致性能恶化。
典型:统计信息自动收集、绑定变量窥探、cursor invalid、基线失效引发计划突变。
按时间顺序输出:
execu_d上涨、物理读
dr_d、IO 等待
io_time上涨如果某个时间窗口
execu_d=0,说明这段时间该 SQL 完全没有跑。
group by + sum 会把同 snapshot、同 plan 的多个实例数据合并汇总,适合 RAC 整体观测这条 SQL 的全局负载。
v$sqlstat / v$sql。
如果 AWR 采样间隔 1h,只能按小时粒度看,看不到分钟级抖动(可以调整 AWR 采集间隔)。END_INTERVAL_TIME是快照
结束时间,该行指标代表【上一个 snap → 当前 snap】这一段时间,
不是这个时间点瞬间的数据。sysdate-6如果超过 AWR 保留周期,部分时间段无结果;
可查询
dba_hist_wr_control 查看 AWR 保留天数。execu_d=0,et_onetime 直接等于总耗时,业务上没有实际意义,仅用来规避除 0 异常。dba_hist_*,需要 DBA 授予
SELECT_CATALOG_ROLE;
12c/19c CDB 架构,需要在 CDB 查询或者使用 PDB 对应的视图,否则查不到数据。PX并行信息,并行 SQL 的 elapsed_time 会包含并行总耗时,单次耗时解读要小心。select to_char(b.END_INTERVAL_TIME,'yyyymmddhh24mi') shijian, a.plan_hash_value plan_hash, sum(a.EXECUTIONS_DELTA) execu_d, sum(a.BUFFER_GETS_DELTA ) bg_d, sum(a.DISK_READS_DELTA ) dr_d, round(sum(a.ELAPSED_TIME_DELTA/1000000),4) et_d, round(sum(a.CPU_TIME_DELTA/1000000),4) ct_d, round(sum(IOWAIT_DELTA/1000000),4) io_time, round(sum(CLWAIT_DELTA/1000000),4) clus_time, round(sum(APWAIT_DELTA/1000000),4) ap_time, round(sum(ccwait_delta/1000000),4) cc_time, -- 增加单次逻辑读,判断是否计划变差 decode(sum(a.EXECUTIONS_DELTA),0,0,round(sum(a.BUFFER_GETS_DELTA)/sum(a.EXECUTIONS_DELTA),2)) bg_onetime, decode(sum(a.EXECUTIONS_DELTA),0,0,round(sum(a.ELAPSED_TIME_DELTA/1000000)/sum(a.EXECUTIONS_DELTA),4)) et_onetime from dba_hist_sqlstat a, dba_hist_snapshot b where a.SNAP_ID =b.SNAP_ID and a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.sql_id='&sql_id' and b.END_INTERVAL_TIME >= sysdate - 6 group by to_char(b.END_INTERVAL_TIME,'yyyymmddhh24mi'),a.plan_hash_value order by 1,2;
dbms_xplan.display_awr('&sql_id',&plan_hash) 查看新旧执行计划对比
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12798004/viewspace-3180748/ ,如需转载,请注明出处,否则将追究法律责任。