PARALLEL提示未生效是因为并行查询未触发实例间分发,常见原因包括表未启用并行属性、parallel_force_local=TRUE、统计信息陈旧、存在无法并行的谓词或ORDER BY导致全局排序瓶颈。
为什么 PARALLEL 提示没生效,查的还是单实例?
oracle rac 下全表扫描不跨实例,本质是并行查询(pq)未触发实例间分发。默认情况下,即使加了 /*+ parallel(t 4) */,oracle 也可能只在本节点启动并行进程(px),尤其当表段未启用 parallel 属性、或 parallel_force_local = true 时。
- 检查表是否真正支持跨实例并行:
SELECT degree, instances FROM dba_tables WHERE table_name = 'YOUR_TABLE';—— 若degree是1或instances是1,强制本地执行 - 确认参数:
SHOW PARAMETER parallel_force_local,若为TRUE,必须显式设为FALSE(需ALTER SYSTEM或会话级ALTER SESSION SET parallel_force_local = FALSE) - RAC 中真正触发跨实例 PX 的关键,是让 coordinator 进程把 slave 分配到其他节点 —— 这依赖于
parallel_instance_group配置和各节点负载均衡策略,不是光靠 hint 就能决定的
V$PQ_TQSTAT 显示只有 Q000,没看到 Q101/Q201 这类从属进程?
这说明并行执行根本没有启动,或者被降级为串行。常见于统计信息陈旧、优化器估算行数极小、或存在无法并行的谓词(如某些 UDF、ROWNUM、非确定性函数)。
- 运行前先查执行计划:
EXPLAIN PLAN FOR SELECT /*+ PARALLEL(t 8) */ * FROM t WHERE ...;,再SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);—— 看IN-OUT列是否含P->P(Producer-Consumer)或P->S(Producer-Serial) - 避免在
WHERE子句中使用SYSDATE、USER、自定义 PL/SQL 函数(除非声明为DETERMINISTIC且PARALLEL_ENABLE) - 大表务必确保有最新统计信息:
DBMS_STATS.GATHER_TABLE_STATS,否则优化器可能因低估数据量而放弃并行
用 PARALLEL_DEGREE_POLICY = AUTO 反而变慢?
自动并行度策略在 RAC 上容易误判资源水位,导致分配过多 slave 占满所有节点 CPU,或因等待跨节点消息引入高 gc cr block busy 等待事件,实际吞吐反而下降。
- 生产环境更推荐显式控制:
PARALLEL_DEGREE_POLICY = MANUAL,配合表级ALTER TABLE t PARALLEL 8和会话级ALTER SESSION FORCE PARALLEL QUERY PARALLEL 8 - 注意
parallel_max_servers设置 —— RAC 每个实例独立计数,若设为 40,两节点共 80 个 PX 进程,极易挤占后台进程内存 - 监控真实并行消耗:
SELECT server_name, status, degree, req_degree FROM v$px_session;,对比req_degree(请求并行度)和degree(实际获得),差值大说明资源争用严重
全表扫描 + ORDER BY 导致大量 TEMP 表空间写入?
并行排序(ORDER BY)在 RAC 中默认触发“全局排序”,所有节点的 PX 进程需把数据汇总到 coordinator 节点再排,网络传输 + 单点排序成为瓶颈,temp 使用暴增且延迟陡升。
- 如果业务允许近似有序,考虑去掉
ORDER BY,或改用应用层聚合 - 若必须排序,优先让数据物理有序:建表时按常用排序字段做
CLUSTERING(12c+)或用 IOT,减少排序输入量 - 极端场景可强制本地排序:
/*+ NO_GBY_PUSHDOWN */hint(19c+),但需验证结果一致性 —— 它绕过全局排序逻辑,只保证每个实例内有序
跨实例并行真正的难点不在开启,而在资源感知与数据分布对齐。比如 hash 分区表没按并行度对齐分区数,或 parallel_adaptive_multi_user 在高并发下反复升降级,这些细节比加几个 hint 更影响实际效果。


















