ash无法准确反映大批量delete真实开销,因其执行快、等待少、采样易遗漏,且undo/索引/日志开销分散于后台进程;应结合v$session_event、awr报告和归档日志速率综合诊断。
直接查 v$active_session_history 看不到大批量 delete 的真实开销——因为这类操作常不等待、不显式阻塞,ash 样本稀疏甚至完全缺失;必须结合 v$session_event、awr 的 top events 和日志生成速率交叉验证。
为什么ASH里几乎看不到DELETE语句的活跃样本
大批量 DELETE(尤其带 /*+ APPEND */ 或分区级操作)往往执行快、等待少,ASH 每秒采样一次,极易错过。更关键的是:DELETE 本身不触发 direct path write temp 这类明显等待事件,它主要消耗在 UNDO 写入、索引维护和日志刷盘上,而这些动作分散在多个后台进程(如 ora_dbw0_*、ora_lgwr_*)中,ASH 默认只记录前台会话的“当前状态”,不自动关联后台链路。
- UNDO 表空间争用不会体现为前台会话的
event,而是反映在v$session_event中的enq: US - contention或undo segment extension - 索引块分裂导致的 CPU 毛刺,在 ASH 中表现为
ON CPU但sql_id指向索引 DML 的递归 SQL,而非原始DELETE语句 - 若
DELETE走了全表扫描 + 大量逻辑读,event可能是db file sequential read,但样本集中在扫描阶段,删数据本身那几毫秒根本没被捕获
该查哪些视图替代ASH抓DELETE瓶颈
别死守 ASH。真正有效的三板斧是:v$session_event 实时抓等待、AWR 报告看聚合趋势、归档日志生成速率判断提交频次。
- 立刻执行:
SELECT sid, event, p1text, p1, p2text, p2, seconds_in_wait FROM v$session_event WHERE event IN ('log file sync', 'enq: US - contention', 'db file sequential read') AND sid IN (SELECT sid FROM v$session WHERE module = 'BatchDelete' OR program LIKE '%sqlplus%');—— 比等 ASH 出结果快 10 秒以上 - 生成最近 30 分钟 AWR 报告,重点看 “Top 5 Timed Events” 中
log file sync占比是否超 30%,以及 “SQL Statistics → SQL ordered by Gets” 是否有高逻辑读的DELETE语句 - 查归档速率突增:
SELECT TRUNC(first_time,'HH24'), COUNT(*) * 100/60 FROM v$log_history WHERE first_time > SYSDATE - 1/24 GROUP BY TRUNC(first_time,'HH24') ORDER BY 1;—— 若某分钟归档量翻倍,基本可断定是COMMIT频次过高,而非单条DELETE慢
MODULE字段为空时怎么定位DELETE会话
MODULE 字段为空不是 ASH 的问题,是应用没调用 DBMS_APPLICATION_INFO.SET_MODULE。不能靠它过滤,得换锚点。
- 用
program+machine组合:比如program LIKE 'sqlplus@%'且machine = 'etl-server-01',比猜MODULE更稳 - 查
v$session中sql_id对应的sql_text:SELECT sql_text FROM v$sql WHERE sql_id = 'abc123xyz';—— 如果开头是DELETE FROM orders WHERE created_date ,就不用管 <code>MODULE是什么了 - 若用 JDBC 批处理,
client_identifier字段有时比MODULE更可靠,前提是应用层调用了conn.setClientIdentifier("batch-delete-job")
容易被忽略的DELETE隐性开销点
很多人盯着 elapsed_time,却漏掉三个更致命的损耗源:索引分裂导致的块争用、UNDO 回滚段扩展失败、以及统计信息失效引发后续查询计划劣化。
- 索引分裂:执行
DELETE后立刻查v$segment_statistics,看目标表索引的gc cr block busy或enqueue waits是否飙升 —— 这说明 B-Tree 结构正在高频重排 - UNDO 扩展失败:监控
v$undostat的unxpstealcnt(非到期块被偷用次数),值持续 > 0 表示 UNDO 表空间不足,DELETE会被迫串行化 - 统计信息滞后:
DELETE掉 90% 数据后,旧统计信息会让优化器误判选择全表扫描,实际只需走索引。必须手动EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA','TABLE');,不能等自动任务











