PARALLEL提示未生效的根本原因是Oracle未触发跨实例并行,常见原因有三:表DEGREE或INSTANCES为1、parallel_force_local=TRUE、优化器因统计陈旧或不可并行谓词而降级为串行。
PARALLEL 提示没生效?先确认表级并行属性和实例分发开关
加了 /*+ parallel(t 8) */ 却只在单节点跑,根本原因是 oracle 没触发跨实例并行(pq)。常见卡点有三个:degree 和 instances 都是 1、parallel_force_local = true、或优化器估算行数太小直接降级为串行。
查表真实并行能力:SELECT degree, instances FROM dba_tables WHERE table_name = 'YOUR_TABLE';
若 degree = 1 或 instances = 1,说明表段未启用并行,需执行:ALTER TABLE your_table PARALLEL 8;(注意:不带 INSTANCES 子句时,默认继承系统级设置)
检查会话/系统级参数:SHOW PARAMETER parallel_force_local
若返回 TRUE,必须显式关闭:ALTER SESSION SET parallel_force_local = FALSE;
否则即使 hint 写对,也强制本地执行。
为什么执行计划里看不到 Q101/Q201 这类并行进程?
执行计划中只有 Q000(coordinator),没出现从属进程(如 Q101、Q201),说明并行根本没启动。这不是 hint 问题,而是优化器主动放弃并行——常见诱因:
- 统计信息陈旧,
NUM_ROWS被低估,优化器认为“这表才 1 万行,串行更快” -
WHERE子句含无法并行的谓词:SYSDATE、USER、未声明DETERMINISTIC的自定义函数、ROWNUM - 存在
ORDER BY导致全局排序瓶颈,优化器选择串行 + Buffer Cache 路径
务必先看真实执行计划:EXPLAIN PLAN FOR SELECT /*+ parallel(t 8) */ * FROM t WHERE ...;SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
重点看 IN-OUT 列:出现 P->P(Producer-Consumer)才表示跨实例并行已激活;若为 P->S,说明部分操作被强制串行化。
Direct Path Read 没触发?检查对象大小与参数阈值
全表扫描走 direct path read 而非 db file scattered read,核心条件是“绕过 Buffer Cache 直读磁盘”。Oracle 19c 默认启用该行为,但前提是满足阈值:
- 表段大小 >
_small_table_threshold(默认约 Buffer Cache 的 2%) - 或显式启用:
ALTER SESSION SET "_serial_direct_read" = ALWAYS; - 或使用 hint:
/*+ direct */(仅限 19c 及以上)
查当前阈值:SELECT ksppinm, ksppstvl FROM x$ksppi a, x$ksppcv b WHERE a.indx = b.indx AND ksppinm = '_small_table_threshold';
若表远大于该值却仍走 scattered read,大概率是 buffer_cache 中已有大量该表块(比如刚做过串行查询),Oracle 认为“缓存命中率高,没必要绕开”,此时可临时清空:ALTER SYSTEM FLUSH BUFFER_CACHE;(仅测试环境用)
并行 + Direct Path Read 组合下,PGA 和 I/O 压力怎么平衡?
并行度 8 时,每个从属进程都会分配独立 PGA 内存来接收 direct path 数据,总内存消耗 ≈ 8 × pga_aggregate_target 的单进程上限。容易踩的坑:
-
pga_aggregate_target设置过低 → 大量direct path read temp等待,排序/聚合被迫写入 TEMP 表空间 - 异步 I/O 未启用(
disk_asynch_io = FALSE)→direct path read等待时间统计失真,实际 I/O 吞吐上不去 - 存储层未对齐(如 ASM AU 大小 ≠ 文件系统 block size)→ 物理读块数暴增,
P3值异常高
验证是否真走 direct path:
查 AWR 或实时 v$session_event:SELECT event, p1text, p1, p2text, p2, p3text, p3 FROM v$session_event WHERE event = 'direct path read' AND sid = &sid;
若 P3(block count)持续 ≥ 128,基本确认是大块直读;若频繁出现 P3 = 1,说明实际退化为单块读,得回头检查并行是否真生效。



















