如何通过AWR分析业务低谷期_利用夜间快照评估批处理作业耗时
夜间批处理作业在AWR报告中消失?先检查DBA_HIST_ACTIVE_SESS_HISTORY的采样覆盖
许多Oracle DBA都曾面临这样的困扰:明明在凌晨时段,批处理任务正在密集执行,但事后查看AWR性能报告时,相关的会话活动和SQL语句却“神秘失踪”。这通常并非数据丢失,而是由AWR的采样机制与作业执行窗口不匹配导致的。AWR默认每小时(60分钟)采集一次系统快照,而大量批处理作业恰恰选择在凌晨2点至4点这样的维护窗口内运行。如果某个作业执行时长较短(例如仅8分钟),且其运行时段恰好落在两次快照采集的时间点之间,那么它在AWR报告中就很可能无法被捕捉到。这本质上是采样频率未能覆盖作业执行节奏的问题。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
当遇到批处理作业在AWR中“隐身”的情况,建议按照以下步骤进行排查:
- 首先,查询
DBA_HIST_SNAPSHOT历史快照视图,确认你所关注的时间段内是否存在有效的快照记录。这是定位问题的基本前提。SELECT snap_id, begin_interval_time, end_interval_time FROM DBA_HIST_SNAPSHOT WHERE begin_interval_time >= DATE '2024-04-10' AND end_interval_time <= DATE '2024-04-11' ORDER BY snap_id;
- 如果确认快照间隔过大,可以考虑临时提高AWR快照的采集频率(此操作需要DBA权限),例如将间隔调整为15分钟:
EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(interval => 15);。请注意,此调整仅对后续快照生效,并且会增加AWR资料库的存储开销。 - 更通用且高效的方法是直接查询
DBA_HIST_ACTIVE_SESS_HISTORY(ASH)历史活跃会话数据。ASH的采样粒度更细,默认每秒捕获一次活跃会话信息(通常保留30分钟,可配置延长),是追溯和分析短期批处理作业活动的理想工具。
如何从AWR报告中快速找出耗时最长的批处理SQL?
切勿盲目地在AWR报告数十页的“SQL统计信息”表格中进行大海捞针。该部分通常按SQL的总执行时间、逻辑读或执行次数进行排序。然而,真正导致业务延迟的“罪魁祸首”,往往是那些执行次数极少(可能仅一次)、但单次运行就耗时几十分钟的批处理SQL。这类SQL在按总量排序的榜单中,很难进入前十名。
要精准定位此类高单次耗时的SQL,需要转换分析思路:
- 生成AWR报告时,在“报告级别”选择
Typical或ALL,确保报告包含Top SQL with Top Events(关联顶级等待事件的SQL)这一关键章节。 - 重点关注“每次执行耗时(秒)”这一列,而非仅仅查看“总耗时(秒)”。对于单次执行时间超过10秒的SQL,都应展开其详细内容进行审查。
- 你也可以直接查询
DBA_HIST_SQLSTAT历史SQL统计视图进行手动筛选和排序,这种方式更为灵活:SELECT sql_id, elapsed_time_delta/decode(executions_delta,0,1,executions_delta)/1000000 elap_per_exec FROM DBA_HIST_SQLSTAT WHERE snap_id BETWEEN 12345 AND 12346 AND executions_delta > 0 ORDER BY elap_per_exec DESC FETCH FIRST 5 ROWS ONLY;
- 这里有一个关键细节需要警惕:如果
executions_delta为0,意味着该SQL在快照区间内未执行完成或被取消。此时,elapsed_time_delta记录的是累计的等待与执行时间,不能简单地用它除以执行次数来计算平均单次耗时。
为什么在DBA_HIST_SQL_PLAN中找不到批处理SQL的执行计划?
这是另一个常见的误区。AWR并不会保存所有SQL语句的完整执行计划历史,它通常只存储那些被内部阈值判定为“高负载”的语句,或者在生成AWR报告时被显式捕获到的计划。许多批处理作业为了提高灵活性,会采用绑定变量结合动态SQL拼接的方式,导致SQL_ID频繁变化。在数据库看来,这些并非需要长期监控的“稳定对象”,因此其执行计划很可能不会被收录到历史视图中。
若需查找此类SQL的执行计划,可以尝试以下方法:
- 最直接的方法是在作业仍在运行时,立即查询
V$SQL_PLAN动态性能视图(这是实时视图,非历史视图),它反映了当前库缓存中最真实的执行计划:SELECT * FROM V$SQL_PLAN WHERE sql_id = 'abc123xyz';
- 如果作业已经结束,且未开启
FORCE_MATCHING_SIGNATURE功能,可以尝试通过DBA_HIST_SQLTEXT历史SQL文本视图,使用SQL文本片段进行模糊匹配,先反推出可能的sql_id,再进一步查找其计划。 - 从长远来看,一个治本的方案是在批处理脚本的关键SQL语句前添加
/*+ MONITOR */优化器提示。此提示会强制Oracle将该SQL的执行详情记录到V$SQL_MONITOR实时监控视图中,并且有很大概率被AWR捕获留存。 - 最后请注意:
DBA_HIST_SQL_PLAN历史视图中的plan_hash_value(计划哈希值),可能与V$SQL_PLAN实时视图中的不完全一致。历史视图中的计划可能经过截断或归一化处理。
评估批处理性能,仅看AWR中的DB Time和DB CPU就足够了吗?
显然不够,尤其是对于夜间批处理这类复杂场景。DB Time(数据库时间)数值高,可能仅仅是因为存在大量的I/O等待(例如db file sequential read顺序读)或锁等待(例如enq: TX - row lock contention行锁竞争)。而这些等待事件在AWR报告的汇总页面中,很可能被归并到“Other”(其他)或“Background”(后台)分类里,仅凭一眼扫过难以发现真正的性能瓶颈。
因此,进行性能评估时必须进行更深入的分析:
- 必须仔细研读AWR报告的“等待事件”部分,特别是
Top 5 Timed Foreground Events(前5个定时前台等待事件)表格。排序依据应重点关注% DB Time(占数据库时间的百分比),而非绝对的等待时间毫秒数。 - 如果在此处观察到大量的
direct path read(直接路径读)等待事件,通常意味着批处理正在进行全表扫描或并行数据加载。此时需要检查相关表是否缺少合适的索引,或者表的统计信息是否已经过期。 - 另一个重要的对比分析是:计算两个相邻快照之间
DB Time的差值,然后对比同一时间段内实际的Elapsed Time(即真实流逝的墙钟时间)。如果DB Time远小于Elapsed Time,则表明有大量时间消耗在了数据库之外,例如网络传输、应用层逻辑处理或调用外部API——这些是AWR监控的盲区。 - 最后,切勿忽略资源管理器的影响。夜间批处理作业常常受到
Resource Manager(资源管理器)策略的限制。建议检查DBA_RSRC_CONSUMER_GROUP_PRIVS以及当前会话的resource_consumer_group值,确认作业没有因为资源配额不足而在队列中等待。
归根结底,批处理作业的性能问题从来不是单一因素造成的。它是SQL语句效率、执行计划稳定性、系统等待事件、资源配额限制以及外部依赖共同作用下的一个“复合体”。AWR快照如同切片观察,如果切片的位置不准,或者切片过厚,就难以看清全貌。理解AWR的采样机制与局限性,并综合运用ASH、SQL监控等多维度工具,才是有效诊断和优化批处理性能的关键所在。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
SQL如何调试复杂的嵌套查询_利用EXPLAIN分析执行路径
SQL如何调试复杂的嵌套查询:利用EXPLAIN分析执行路径 调试复杂SQL,尤其是嵌套查询,最怕的就是面对执行计划一头雾水。其实,读懂EXPLAIN的输出,关键在于理解优化器背后的权衡逻辑,而不是死记硬背几个术语。下面这几个常见的执行计划“疑点”,就是很好的切入点。 EXPLAIN 看不懂执行计划
mysql如何将时间戳转为日期_使用from unix time函数转换
MySQL中FROM_UNIXTIME()转换时间戳需注意时区、引号、NULL及类型溢出 在MySQL数据库操作中,将时间戳转换为可读日期是常见需求,FROM_UNIXTIME()函数是实现这一功能的核心工具。然而,实际应用中存在四个关键细节极易被忽视,直接影响数据准确性:必须使用 +08:00 格
mysql如何将表定义转化为JSON格式_数据库结构文档化技巧
MySQL表结构转JSON:避开常见陷阱,实现高效文档化方案 你是否需要将MySQL的表定义转换为一份清晰、可直接使用的JSON文档?这项工作听起来简单,但实际操作中,直接解析SHOW CREATE TABLE命令的输出会遇到格式不统一的问题,容易出错。有没有更稳定可靠的方法?答案是肯定的。 利用
SQL如何高效合并两个结构相似的表_使用UNION_ALL代替不必要的JOIN
SQL如何高效合并两个结构相似的表:使用UNION ALL代替不必要的JOIN 想把两个结构相似的表合并起来,你首先想到的是不是JOIN?其实,在很多场景下,UNION ALL才是那个更直接、更高效的选择。关键在于,你得先搞清楚自己的目标:是要把数据“纵向堆叠”起来,还是要“横向关联”起来。前者是U
mysql如何定期清理过期测试数据_mysql数据生命周期管理
MySQL测试数据清理:从“能删”到“会删”的四个关键步骤 清理数据库中的过期测试数据,看似是一项基础的运维任务,实则蕴含着诸多技术细节与风险考量。直接执行DELETE语句固然简单,但如何高效、安全、可控地完成清理,才是衡量专业度的关键。 用 DELETE + WHERE 清理过期测试数据最直接,但
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

