parallel join本质是将单线程join任务拆分给多个px进程并行执行,通过切片扫描、连接、聚合等阶段并由px coordinator汇总结果,绕过串行瓶颈以充分利用硬件资源。

Parallel Join 本质是把单线程任务拆给多个PX进程干
Oracle 默认对 JOIN 操作走串行执行,哪怕两表都上亿、CPU 有 32 核,也只用 1 个进程扫完再连。Parallel Join 改变的是执行模型:优化器把大表扫描、连接、聚合这些阶段切片,分发给多个并行服务器进程(PX)同时处理,最后由 PX COORDINATOR 汇总结果。这不是“加了 hint 就快”,而是强制绕过串行瓶颈,让硬件资源真正被填满。
/*+ parallel(t, n) */ 的表名和别名必须严格匹配执行计划中的对象
常见错误是写错对象标识导致 Parallel 完全失效——比如表 statcmain 起了别名 a,但 hint 写成 /*+ parallel(statcmain, 8) */,而执行计划里该表显示为 a,Oracle 就不会启用并行。实际生效只看执行计划中 Object Name 列的值。
- 查执行计划时重点关注
Operation列是否出现PX SEND、PX RECEIVE、PX COORDINATOR - 如果用了
JOIN,确保 hint 同时作用在参与连接的大表上,例如/*+ parallel(a,8) parallel(b,8) */ - 别名优先于表名;没别名才用原表名;大小写敏感(尤其在双引号引用的表名场景)
并行度(DOP)不是越高越好,超配反而拖慢整体吞吐
设 DOP = 16 不代表真能跑满 16 个进程。Oracle 实际分配受 PARALLEL_MAX_SERVERS、当前空闲 PX 进程数、以及系统负载共同限制。更关键的是:高 DOP 会争抢内存(PGA)、I/O 带宽和 CPU 缓存,尤其当多个 Parallel SQL 并发时,容易触发 enq: KO - fast object checkpoint 或大量 direct path read temp 等等待事件。
- 经验值:DOP ≤
CPU_COUNT - 1,且不超过PARALLEL_THREADS_PER_CPU × CPU_COUNT - 批处理中若含
INSERT /*+ append */,注意并行 DML 需显式开启ALTER SESSION ENABLE PARALLEL DML - 用
V$PQ_SESSTAT查当前会话并行统计,比盲目调高 DOP 更有效
Parallel Join 的收益高度依赖数据分布与连接键选择性
并行对 HASH JOIN 最友好,因为哈希分区天然可切分;但对 NESTED LOOPS 效果有限——内表驱动循环仍可能串行执行。如果连接条件无索引、或连接键重复率极高(如几十万行都匹配同一个 group_id),并行后各 PX 进程仍要反复扫描同一块内表数据,I/O 和 CPU 反而浪费。
- 先确认执行计划中
JOIN类型是HASH JOIN或MERGE JOIN,而非NESTED LOOPS - 连接字段必须有统计信息(
DBMS_STATS.GATHER_TABLE_STATS),否则优化器可能误判选择性,放弃并行或选错连接方式 - 大表关联小表时,小表未必需要并行;重点并行扫描大表 + 用小表构建广播哈希表(
USE_HASHhint 配合)
实际批处理中,并行收益常卡在数据倾斜或临时段争用上,而不是 DOP 数字本身。真正压测前,得先看 DBA_HIST_SQL_PLAN 里历史执行的真实并行行为,而不是只盯着 hint 写没写对。











