游乐游手机版
首页/数据库/文章详情

Oracle 19c ASH分析特定模块CPU消耗方法

时间:2026-06-27 06:55
在进行Oracle数据库性能分析时,有一个关键要点必须牢记:查询时必须加上 session_state = ON CPU ,因为 MODULE 字段仅标识应用模块,并不能区分当前会话是处于执行状态还是空闲等待。如果遗漏这一条件,统计结果会混入大量等待、空闲等无效样本,容易将“慢模块”误判为“CPU

在进行Oracle数据库性能分析时,有一个关键要点必须牢记:查询时必须加上 session_state = 'ON CPU',因为 MODULE 字段仅标识应用模块,并不能区分当前会话是处于执行状态还是空闲等待。如果遗漏这一条件,统计结果会混入大量等待、空闲等无效样本,容易将“慢模块”误判为“CPU消耗较高的模块”——这是不少初学Oracle性能优化的开发者常遇到的问题。

直接查询 v$active_session_history,利用 module 匹配并结合 session_state = 'on cpu',即可准确定位模块级别的CPU资源消耗。但需要特别留意:module 的值可能被应用程序覆盖,且大小写敏感;此外,历史数据的分析必须通过 dba_hist_active_sess_history 视图完成,不能仅依赖内存中的实时视图。

如何通过Oracle 19c的ASH分析特定模块产生的CPU消耗

为什么基于MODULE过滤时必须加上session_state = 'ON CPU'

MODULE 字段本质上是由应用层设置的标记(例如在Spring Boot中通过 setModule 方法赋值),它本身并不反映会话当前到底在做什么操作。同一个模块下,会话很可能有大量时间耗费在I/O等待或锁竞争上,真正在CPU上执行的部分只是其中一小部分。如果不加上 session_state = 'ON CPU',统计数据会把各类无效等待样本一并纳入——结果是“响应慢的模块”被误认为是“CPU消耗高的模块”,导致性能优化方向出现偏差。

  • 仅使用 MODULE = 'ORDER-SVC' 过滤:得到的是该模块所有活跃会话的总采样数,包含等待、空闲、解析等各种状态。
  • 增加 AND session_state = 'ON CPU' 条件:才能真实反映该模块在CPU上实际执行的时间占比。
  • 如果模块名来自JDBC的 setClientInfo 方法,需要注意Oracle默认会截断为48字节,超出部分会被静默丢弃。

MODULE值的大小写与空格问题如何正确处理

Oracle对 MODULE 字段采用精确匹配方式,不会自动去除空格,也不忽略大小写。常见的错误场景是:应用代码中设置了 'payment-gw '(末尾包含空格)或 'Payment-GW',但查询时使用 = 'payment-gw',结果始终无法匹配到数据。

  • 推荐的安全做法:使用 UPPER(TRIM(module)) = UPPER(TRIM('payment-gw')) 进行不区分大小写且去除空格的比对。
  • 先探查模块的实际存储值:执行 SELECT DISTINCT TRIM(module) FROM v$active_session_history WHERE sample_time > SYSDATE - 1/1440 AND module IS NOT NULL AND ROWNUM < 10,确认模块名的真实格式。
  • 尽量避免使用 LIKE '%payment%' 进行全模糊匹配——这种方式容易跨模块误命中,例如 'PAYMENT-GW''REFUND-PAYMENT' 都会被扫描出来,导致分析结果混乱。

查询历史模块CPU消耗必须使用DBA_HIST_ACTIVE_SESS_HISTORY

v$active_session_history 仅保留最近约1小时的内存数据。如果需要分析昨天下午3点 MODULE = 'INVOICE-BATCH' 的CPU使用情况,必须切换到磁盘归档视图。但这里有一个重要的限制:DBA_HIST_ACTIVE_SESS_HISTORY 中的 MODULE 字段只记录AWR快照时刻的值,并非每秒采样都会保留,因此精度会有所下降——它只能反映快照周期内(默认60分钟)该模块是否活跃过,无法捕捉瞬时的性能尖刺。

  • 必须显式指定时间范围:使用 sample_time BETWEEN TIMESTAMP '2026-06-12 15:00:00' AND TIMESTAMP '2026-06-12 16:00:00',不要简单写成 SYSDATE - 1
  • 在RAC环境下,该视图已经聚合了所有实例的数据,无需手动执行 UNION ALL;但可以通过 instance_number 字段下钻到单个节点进行分析。
  • 如果发现历史视图中某个模块的 MODULE 字段为空,很可能是应用程序根本没有设置该字段,或者设置了但被LogMiner、JOB等后台会话覆盖了(后台会话通常会清空MODULE)。

如何将MODULE与具体SQL_ID关联并排除干扰

一个模块可能同时运行数十条SQL语句。如果只知道 MODULE = 'USER-PROFILE' 占用了200个CPU样本,根本无法定位问题的根本原因。必须将 MODULESQL_IDPLAN_HASH_VALUE 三者结合起来进行分析,同时排除解析操作、递归调用等非业务SQL的干扰。

  • 添加 sql_id IS NOT NULL 条件,过滤掉硬解析、PL/SQL执行等没有 SQL_ID 的行。
  • 排除系统内部SQL:使用 AND sql_id NOT IN (SELECT sql_id FROM v$sql WHERE command_type IN (2, 3, 6))(其中2=INSERT, 3=SELECT, 6=UPDATE,其余多为递归或内部操作)。
  • 同一个 sql_id 可能对应多个不同的执行计划,必须加上 sql_plan_hash_value 进行分组,否则低效计划和高效计划混在一起统计,得出的结论将毫无意义。
  • 示例查询语句:SELECT module, sql_id, sql_plan_hash_value, COUNT(*) cpu_samples FROM dba_hist_active_sess_history WHERE module = 'USER-PROFILE' AND session_state = 'ON CPU' AND sample_time BETWEEN ... GROUP BY module, sql_id, sql_plan_hash_value ORDER BY cpu_samples DESC

MODULE 是应用层可观测性的重要入口,但它本身并不携带执行上下文信息。定位到高CPU消耗的模块后,下一步必须深入到 SQL_ID + 执行计划 + 绑定变量 的组合分析——否则你优化的只是表面现象,而非真正的执行逻辑。

来源:https://www.php.cn/faq/2692916.html
上一篇SQL IN子句优化大量固定值筛选的高效技巧 下一篇Oracle 12c ASH分析索引分裂性能延迟诊断方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
如何在PostgreSQL 16中创建带安全限定符的SQL视图详细教程
数据库 · 2026-06-27

如何在PostgreSQL 16中创建带安全限定符的SQL视图详细教程

先说几个核心判断:PostgreSQL 16 的安全视图,不是靠某个内置参数或语法开关就能一劳永逸解决的。它需要一套组合拳来保障——权限、schema 隔离、行级策略,少一个都不行。 PostgreSQL 16 安全视图的“三重卡死”机制 PostgreSQL 16 本身并不支持带参数的视图。

SQL视图定义中为何不建议使用SELECT * 而应明确列名
数据库 · 2026-06-27

SQL视图定义中为何不建议使用SELECT * 而应明确列名

从语法层面来看,在SQL视图定义中使用SELECT *本身并不构成语法错误。然而,从数据库设计与架构优化的角度审视,这种做法几乎等同于主动放弃了对于输出结果集的精确掌控——视图一旦创建,其列名、列顺序以及列数量理应是明确且固定的,而*通配符却让这一切变成了运行时才揭晓的未知数。视图列结构会因底层表变

SQL Server GROUP BY非聚合列报错解决方法
数据库 · 2026-06-27

SQL Server GROUP BY非聚合列报错解决方法

SQL Server 对查询的模糊性零容忍,态度极为明确。一旦 SELECT 列表中包含非聚合列且该列未被 GROUP BY 子句引用,SQL Server 便会立即抛出“列名无效”错误,绝不妥协、猜测或回退。这种严格虽然让新手感到棘手,但也迫使开发者正视查询语义的边界。 然而,许多开发者在遭遇此错

利用SQL嵌套查询检查日期区间重叠有效性
数据库 · 2026-06-27

利用SQL嵌套查询检查日期区间重叠有效性

好的,我将以一位资深数据库专家的视角,对原文进行人性化重写,保留所有核心信息、逻辑结构与图片,同时去除AI腔调,让语言更自然、有节奏,并谨慎控制第一人称的使用。 --- 日期区间重叠检查,这事儿的坑比想象的多。写 SQL 时,很多人总想着先写个函数或者建个临时表来比对,其实没必要——直接上自连接加个

Oracle 12c RAC环境下RMAN恢复共享数据文件
数据库 · 2026-06-27

Oracle 12c RAC环境下RMAN恢复共享数据文件

在RAC环境下使用RMAN恢复共享数据文件,很多DBA第一次遇到时都会感到棘手:备份文件明明完整,执行RESTORE DATABASE却报ORA-01102或ORA-01507。别紧张,这并非命令错误,而是RAC的共享存储与多实例并发机制与RMAN恢复流程存在根本性的不兼容。 RMAN在RAC下无法