查不到px等待事件需用gv$active_session_history,因rac中px进程跨实例分布;关键看time_waited而非sample_count,max(time_waited)>5s表明存在严重并行倾斜。
查不到 px 等待事件?先确认是否用了 gv$active_session_history
在 rac 环境下,v$active_session_history 只记录本实例的采样数据,而并行查询的协调进程(px coordinator)和工作进程(px slave)可能跨节点运行。如果只查单实例视图,px deq: execution message、parallel query dequeue wait 这类关键等待根本不会出现。
必须用 gv$active_session_history,且建议显式按 inst_id 分组比对:
SELECT inst_id, sql_id, event, COUNT(*) cnt FROM gv$active_session_history WHERE sample_time > SYSDATE - 1/1440 AND (event LIKE 'PX %' OR event LIKE 'parallel %') GROUP BY inst_id, sql_id, event ORDER BY cnt DESC;
- 若某
sql_id的等待集中在单一inst_id,说明并行执行未跨节点分布,问题更可能是本地 CPU 或 I/O 资源瓶颈 - 若同一
sql_id在多个inst_id上都有等待,但time_waited差异极大(比如节点2平均 800ms,节点1仅 5ms),就是典型的工作分配不均
time_waited 才是判断倾斜的核心指标,不是 sample_count
ASH 每秒采样一次,COUNT(*) 高只代表“被采到的次数多”,不等于“真卡了那么久”。真正暴露长尾延迟的是 time_waited(单位:微秒),它来自底层等待事件的精确计时。
以下语句能定位最耗时的并行等待样本:
SELECT sql_id, event,
ROUND(AVG(time_waited)/1000, 2) avg_ms,
MAX(time_waited)/1000 max_ms
FROM v$active_session_history
WHERE event IN ('PX Deq: Execution Message',
'PX Deq: Table Q Normal',
'PX qref latch')
AND sample_time > SYSDATE - 1/24
GROUP BY sql_id, event
HAVING MAX(time_waited) > 5000000
ORDER BY max_ms DESC;
-
MAX(time_waited) > 5000000(即 > 5 秒)是硬信号:至少有一个 PX slave 卡住,拖慢整个并行组 - 若
AVG(time_waited)很低但MAX极高,基本可断定是数据分布倾斜或分区裁剪失效,导致某个 slave 扫描远超其他 slave - 别忽略
current_obj#字段:结合dba_objects查出该sql_id正在访问的表,再检查其分区策略和统计信息
为什么 sql_id 显示长时间运行,但实际业务感觉很快?
ASH 记录的是“会话活跃状态”,不是“SQL 执行耗时”。常见误判场景包括:
- SQL 实际执行快,但被阻塞(如
enq: TX - row lock contention)后长时间挂起,ASH 把整个阻塞期都算进“SQL 执行时间” - SQL 被硬解析卡住(比如
library cache lock),ASH 记录的是“parse + execute”总耗时 - SQL 在 PL/SQL 块里循环调用,ASH 每次采样都落在不同迭代上,看起来像单次执行超长
验证方法:查 v$sql 中该 sql_id 的 elapsed_time / executions 平均值,再对比 cpu_time 和 buffer_gets。如果平均 elapsed_time 是 2ms,但 ASH 里有几十条 30s+ 样本,基本可排除真实执行慢,转向查阻塞或解析问题。
并行倾斜常和数据倾斜共存,但二者不能混为一谈
并行倾斜指 PX slave 间工作量不均;数据倾斜指某个过滤值(如 status = 'Z')返回行数远超其他值。两者常互为诱因:
- 没收集直方图时,优化器低估倾斜值的选择性,选了并行全表扫描,结果一个 slave 扫了 90% 的数据
- 即使加了
/*+ PARALLEL(t, 4) */,若表上object_id列严重倾斜且无直方图,WHERE object_id = 10仍可能让一个 slave 处理全部 29 万行 - 查
dba_tab_col_statistics确认histogram是否为FREQUENCY或HEIGHT BALANCED;必要时用method_opt => 'for columns object_id size auto'重收集
真正难缠的是那种“计划看起来没问题、统计信息也新、但某次执行突然巨慢”的情况——十有八九是绑定变量值触发了隐性数据倾斜,而并行机制把它放大成了可观测的执行倾斜。











