根本原因是跨节点调度引入额外开销:全局缓存块传输、进程协调延迟和私网带宽瓶颈,尤其当分区未局部化或DOP过高时,gc current block busy和DFS lock handle等待会急剧放大。

为什么跨节点并行查询反而比单节点还慢?
根本原因不是“并行没开”,而是跨节点调度引入了额外开销:全局缓存块传输(gc cr block 2-way)、进程协调延迟、私网带宽瓶颈。尤其当表分区未按节点局部化、或DOP设置过高时,gc current block busy和DFS lock handle等待会迅速放大。
- 先确认是否真跨了节点:查执行计划的
IN-OUT列,出现PCWP或PCWC才表示有跨节点数据分发;只有PQ说明仍在本节点内并行 - 检查
V$PQ_TQSTAT中各INST_ID的NUM_ROWS分布——若某节点处理量远低于其他节点,说明负载不均,不是并行问题而是调度失衡 - 对比
gv$sysstat里gc cr blocks received与gc current blocks received的比值:若后者显著更高,说明写热点集中,跨节点读取被迫频繁拉取current块,此时加并行只会恶化
PARALLEL提示写了但没跨节点?三个硬性卡点必须检查
常见现象是SQL里写了/*+ PARALLEL(t, 8) */,执行计划却只显示Q000 coordinator,没有Q101等从属进程——这代表并行根本没启动,更别说跨节点了。
- 查表级并行属性:
SELECT degree, instances FROM dba_tables WHERE table_name = 'YOUR_TABLE';若degree = 1或instances = 1,需执行ALTER TABLE your_table PARALLEL 8 INSTANCES 2(显式指定实例数) - 确认
parallel_force_local参数:SHOW PARAMETER parallel_force_local;返回TRUE必须改掉,否则所有hint失效,哪怕DOP设再大也强制本地 - 检查谓词是否可并行:
SYSDATE、USER、未声明DETERMINISTIC的自定义函数、ROWNUM、含ORDER BY的顶层查询,都会导致优化器直接降级为串行
跨节点DOP设多少才合理?别盲目堆数字
DOP不是越大越好。在RAC中,DOP超过单节点可用并行槽位(PARALLEL_THREADS_PER_CPU × CPU_COUNT)后,多余进程才会被调度到其他节点——但这会触发排队和争用。
- 先算单节点最大并行数:
SELECT value FROM v$parameter WHERE name = 'parallel_threads_per_cpu'×CPU_COUNT;例如值为4、CPU为8,则单节点最多32个并行进程 - 设DOP=40时,系统会尝试在节点1起32个、节点2起8个;但若节点2当时已有其他并行任务,剩余8个可能排队,出现
PX Idle Wait - 真正生效的DOP由运行时资源决定,查
V$PQ_TQSTAT的SERVER_TYPE列:若大量显示QC(Query Coordinator)而非PS(Producer Server),说明实际并行度被动态降级了
LMS进程拖慢跨节点并行?别只盯着SQL
跨节点并行依赖LMS进程高效转发缓存块。如果LMS没跑在实时调度模式(SCHED_FIFO),响应延迟升高,会导致GC请求堆积、重试、重复传输——表现为CPU高但吞吐低,gc cr multi block request耗时陡增。
- 检查alert log是否有
at elevated (RT) priority字样;没有就说明LMS未启用RT调度 - 用
ps -eo pid,comm,cls,pri,rtprio,%cpu | grep LMS确认cls列是否为ff(SCHED_FIFO);若是ts,需检查/etc/security/limits.conf是否配置oracle soft rtprio 99,并执行kill -SIGUSR2 <lms_pid></lms_pid>重载策略 - 盲目增加
_lm_lms参数(如从默认8个调到16个)可能加剧线程切换,尤其在2节点RAC中,_lm_lms=4通常已足够,重点应调_gc_policy_time(默认10秒)缩短策略计算周期
跨节点并行的瓶颈往往不在SQL写法本身,而在LMS调度、GC块传输路径、以及实例间私网质量——这些地方出问题,再好的hint也救不了。


















