怎么利用Oracle AWR中的ASH数据分析特定时段的CPU瓶颈

星敏小哥_9292

星敏小哥_9292

2026-09-23

450人浏览

原创

ash是独立于awr的实时采样源,v$active_session_history每秒采样,dba_hist_active_sess_history为其归档,awr则为定时聚合统计;排查瞬时性能问题必须用ash。

怎么利用oracle awr中的ash数据分析特定时段的cpu瓶颈

ASH数据不是AWR的子集,而是独立采样源

很多人误以为ASH是AWR里“抽出来的一小部分”,其实完全相反:v$active_session_history 是内存中每秒采样的实时快照,dba_hist_active_sess_history 才是它的持久化归档;而AWR快照(dba_hist_snapshot)只是定时打包的聚合统计。两者时间对齐但逻辑隔离——你不能指望在AWR报告里“点开ASH详情”,必须单独查ASH视图或生成ASH报告。

关键区别在于:AWR告诉你“过去一小时谁平均占CPU多”,ASH告诉你“第37分22秒是谁正在吃满一个核”。排查瞬时CPU尖峰、短时锁争用、单条SQL突发高CPU,必须用ASH。

  • 默认ASH内存保留约1小时(V$ACTIVE_SESSION_HISTORY),历史归档保留8天(DBA_HIST_ACTIVE_SESS_HISTORY),但需注意:归档数据可能被压缩或采样降频,尤其在高负载时段
  • 查不到最近1小时数据?先确认是否启用了ASH:检查SELECT value FROM v$parameter WHERE name = 'statistics_level',值必须是ALLTYPICALBASIC会禁用ASH)
  • 生产库若发现DBA_HIST_ACTIVE_SESS_HISTORY为空,大概率是SYSAUX表空间满或_ash_disk_filter_ratio隐含参数被调得过高(不建议手动改)

直接查dba_hist_active_sess_history定位高CPU会话

别等报告生成,用SQL直击核心。目标很明确:找出指定时间段内,session_state = 'ON CPU'sql_id 非空的记录,并按CPU消耗聚合。

示例(查今天14:00–15:00的CPU热点):

Market Oracle
Market Oracle

金融事件影响分析器 — 获取突发新闻,追踪金属/石油/加密货币/股票价格,预测短中长期市场连锁反应

下载
SELECT sql_id, 
       COUNT(*) as cpu_samples,
       ROUND(COUNT(*) * 10, 2) as cpu_sec_estimated,
       COUNT(DISTINCT session_id) as active_sessions
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN TIMESTAMP'2026-08-26 14:00:00' 
                      AND TIMESTAMP'2026-08-26 15:00:00'
  AND session_state = 'ON CPU'
  AND sql_id IS NOT NULL
GROUP BY sql_id
ORDER BY cpu_samples DESC
FETCH FIRST 10 ROWS ONLY;
  • COUNT(*) * 10 是估算依据:ASH每秒采样1次,但归档表默认每10秒存1条(即采样率≈0.1Hz),所以每个样本≈10秒CPU时间——这是最常被忽略的换算系数
  • 结果里cpu_sec_estimated超过你实例总CPU秒数(如4核×3600秒=14400秒),说明该SQL反复执行、或并行度高、或存在大量递归调用
  • 如果sql_id0000000000000000 或全为字母数字但查dba_hist_sqltext为空,大概率是PL/SQL匿名块、触发器、或硬解析失败的语句,需结合programmodule字段判断来源

为什么sql_id 对应的SQL文本查不到?

v$sqldba_hist_sqltext 都可能找不到对应文本,原因不同,处理方式也不同:

  • v$sql 里没有 → SQL已被老化(aged out),必须查dba_hist_sqltext;但要注意:Oracle 11g+才支持sql_fulltext字段,10g只能看到前1000字符,容易误判谓词条件
  • dba_hist_sqltextsql_text 显示为 /* SQL Analyze(123) */ SELECT ... → 这是DBMS_SQLTUNE自动SQL分析任务生成的,不是业务SQL;此时要结合program = 'oracle@host (J000)'module = 'DBMS_SCHEDULER' 确认是否为维护作业
  • sql_id 存在但sql_fulltext 为空 → 可能是DDL(如CREATE INDEX)、密码重置、或审计语句,它们不走SQL引擎,ASH只记状态不记文本
  • dba_hist_sqltext 慢?加条件 WHERE sql_id = 'xxx' AND dbid = (SELECT dbid FROM v$database),避免跨数据库历史数据扫描

结合gv$px_sessiongv$session看并行SQL的CPU分布

RAC或并行环境下,一条SQL的CPU可能分散在多个进程甚至多个节点,只看sql_id聚合会掩盖真相。比如sql_id = 'abc123xyz' 在ASH里显示CPU高,但实际是QC(Query Coordinator)串行部分卡住,而非PX Server并行部分。

  • 先确认是否并行:查SELECT * FROM gv$sql WHERE sql_id = 'abc123xyz' AND px_servers_executions > 0
  • 再看分布:用gv$px_session 查该SQL各PX进程的CPU时间:SELECT qcsid, sid, server_group, server_set, degree FROM gv$px_session WHERE qcsid IN (SELECT sid FROM gv$session WHERE sql_id = 'abc123xyz')
  • 关键陷阱:ASH里session_id 记的是PX Server的SID,不是QC的SID;所以聚合时若没区分qcsid,会把QC的等待(如px qc wait for reply)和PX Server的真实CPU混在一起
  • 真正要盯的是:QC所在会话的event是否为ON CPU,且sql_id 是否与PX Server一致——若不一致,说明QC在跑PL/SQL逻辑或排序,问题不在SQL本身

ASH分析最难的不是查SQL,而是分辨“谁真在干活”:后台进程(Jnnn)、调度作业(CJQn)、并行协调器(QC)、还是前台应用会话。同一个sql_id 在不同program下代表完全不同的风险等级。别跳过programmodule字段,它们才是上下文锚点。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

oracle

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
oracle清空表数据
oracle清空表数据

当表中的数据不需要时,则应该删除该数据并释放所占用的空间。本专题为大家提供oracle清空表数据的相关文章,帮助大家解决该问题。

2023.08.16

821

5

Oracle中declare的使用
Oracle中declare的使用

Oracle DECLARE语句是PL/SQL编程语言中用于声明变量、常量、游标或异常的关键字。它的主要作用是在程序中定义这些对象,以便在后续的代码中使用。DECLARE语句的语法简单明了,可以根据需要声明多个对象。通过使用这些声明的对象,可以进行各种操作,如计算、查询数据库、处理异常等 。

2023.09.15

2233

5

oracle怎么分页
oracle怎么分页

实现分页的步骤:1、使用ROWNUM进行分页查询;2、在执行查询之前进行设置分页参数;3、使用"COUNT(*)"函数来获取总行数,并使用"CEIL"函数来向上取整计算总页数;4、在外部查询中使用"WHERE"子句来筛选出特定的行号范围,以实现分页查询。想了解更多oracle怎么分页的文章,可以来阅读本专题先的文章。

2023.09.18

2270

5

Oracle查看表操作历史记录
Oracle查看表操作历史记录

查看操作历史记录的方法:1、使用Oracle内置的审计功能,可以记录数据库中发生的各种操作,包括登录、DDL语句、DML语句等;2、使用Oracle日志文件,其中包含了数据库中发生的各种操作,可以通过查看日志文件来获取操作历史记录;3、使用Oracle的Flashback功能,可以查看数据库在某个时间点的操作历史记录;4、使用第三方工具等。本专题还提供其他查看表操作的文章,大家可以免费阅读。

2023.09.19

1309

3

Oracle中RAC的用法
Oracle中RAC的用法

Oracle中RAC的用法:1、通过在多个服务器上运行数据库实例来提供高可用性;2、允许在需要时增加或减少节点数量;3、通过将工作负载分布到多个节点上来实现负载均衡;4、使用共享存储来实现多个节点之间的数据共享;5、允许多个节点同时处理数据库请求,从而实现并行处理;6、提供了透明故障切换功能;7、使用了一些技术来确保数据的一致性;8、提供了管理工具来简化RAC环境的管理和维护。本专题还提供RAC相关的其他文章,大家可以免费阅读。

2023.09.19

1893

7

oracle imp
oracle imp

imp是Oracle数据库中的一个命令行工具,用于将导出的数据和对象从一个数据库实例导入到另一个数据库实例。imp命令的一般语法为“imp username/password@connect_string file=file_name [options]”。

2023.09.19

2449

4

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4009

19

oracle通配符有哪些
oracle通配符有哪些

oracle通配符有“%”、“_”、“[]”和“[^]"。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.08

237

5

oracle四舍五入怎么操作
oracle四舍五入怎么操作

oracle四舍五入操作可以使用ROUND函数来实现,其语法为“ROUND(number, decimal_places)”,其中,number是要进行四舍五入的数值,decimal_places是指定的小数位数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.14

626

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程