查不到px相关等待需用gv$active_session_history而非v$,因rac中px进程跨实例分布;关键看time_waited而非sample_count,max(time_waited)>5s表明存在严重并行倾斜。
查不到 px 相关等待?先确认是否用了 gv$ 视图
在 rac 环境下,v$active_session_history 只记录本实例的采样数据,而并行查询的协调(px coordinator)和从进程(px slave)可能分布在不同节点。若只查单实例视图,event 里根本看不到 px deq: execute reply、px deq: signal ack 或 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) - 若
event在多个inst_id上分散但time_waited差异极大(比如节点2平均等 800ms,节点1仅 5ms),就是典型的并行工作分配不均 -
gv$查询结果延迟数秒属正常,别依赖它做毫秒级诊断;关键问题仍需连接各实例单独查v$active_session_history
识别并行倾斜:看 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 -- 超过 5 秒的样本
ORDER BY max_ms DESC;
-
MAX(time_waited)> 5s 是硬信号:说明至少有一个 PX slave 卡住,拖慢整个并行组 - 若
AVG(time_waited)低但MAX极高,基本可断定是数据分布倾斜或分区裁剪失效,导致某个 slave 扫描远超其他 slave - 别忽略
current_obj#:结合dba_objects查出该sql_id正在访问的表,再检查其分区键是否被函数包裹(如WHERE trunc(order_date) = ...),这会让 Oracle 无法裁剪分区
为什么 display_cursor 看不到 PX 操作符?检查 child_number 和 plan_hash_value
执行 dbms_xplan.display_cursor('abc123', null, 'ALLSTATS LAST') 返回空或无 PX 行,常见原因不是没走并行,而是计划已老化或 child cursor 不匹配。
-
null作为child_number参数会默认取0,但活跃并行 SQL 往往运行在非零子游标上;应先查v$sql:SELECT sql_id, child_number, plan_hash_value, loaded_versions FROM v$sql WHERE sql_id = 'abc123' AND executions > 0 - 若
loaded_versions为 0,说明该计划已被 aged out,display_cursor必然查不到;此时只能靠dbms_xplan.display_awr(需 AWR 快照捕获过)或直接查v$sql_plan中operation含PX的行 -
plan_hash_value不同 ≠ 计划退化:Oracle 12c 自适应计划(Adaptive Plans)会在运行时切换分支,display_cursor显示的是最终执行路径,而display_awr可能显示编译时计划——两者差异本身就能说明是否触发了自适应重写
os thread startup 出现时,别急着调大 parallel_max_servers
os thread startup 在 ASH 中高频出现,本质是操作系统线程创建失败,根源几乎全是并行度失控,而非资源池不够。
- 先查源头对象:
SELECT owner, index_name, degree FROM dba_indexes WHERE degree > 1;很多 OLTP 表的索引残留DEGREE > 1,导致普通查询意外触发高 DOP - 禁用方式必须用
ALTER INDEX owner.idx_name NOPARALLEL,重建索引时未指定PARALLEL不等于自动清除degree属性 -
parallel_degree_policy = 'MANUAL'是更安全的全局开关,它让优化器放弃自动并行决策,只响应显式 hint(如/*+ PARALLEL(t, 4) */) - 盲目调大
parallel_max_servers可能加剧 OS 线程争用,尤其在 Solaris 系统上——MOS Doc ID 1909881.1 明确指出该平台对线程创建更敏感
并行倾斜的根因往往藏在对象属性或绑定变量值里,而不是参数数字上;看到 PX 相关等待飙升,第一反应不该是扩容,而是立刻锁定那几条 sql_id 对应的表、索引和执行计划细节。











