oracle 19c单分区精确过滤(如where dt = date '2025-01-01')默认禁用并行,因优化器判定串行更优;需显式指定分区、改写为范围条件或确保分区大小超10mb方可启用并行。

Oracle分区表上加了PARTIAL Hint 却没走并行,大概率不是Hint写错了,而是优化器主动绕开了并行路径——它觉得“只扫一个分区,串行更快”。
为什么单分区精确过滤会让PARTIAL失效?
Oracle 19c 默认对能精准裁剪到单个分区的查询(如WHERE dt = DATE '2025-01-01')禁用并行,哪怕表已设PARALLEL 8。执行计划里看不到PX操作符、v$px_session为空,就是这个原因。
- 必须显式打破裁剪精度:在Hint中指定分区名,例如
SELECT /*+ PARALLEL(t, 4) */ * FROM sales_part t PARTITION (sales_p202501) - 或改写条件为范围/多值,让优化器放弃单分区判断,例如
WHERE dt BETWEEN DATE '2025-01-01' AND DATE '2025-01-31' - 还要检查该分区段大小是否超过
10MB(查DBA_SEGMENTS.BYTES),否则并行启动阈值不满足
为什么RAC环境只在一个节点跑并行?
RAC跨实例并行没触发,常见三个硬性卡点:
-
DEGREE或INSTANCES为1:查SELECT degree, instances FROM dba_tables WHERE table_name = 'YOUR_TABLE',若为1,需执行ALTER TABLE your_table PARALLEL 8 -
parallel_force_local = TRUE:运行SHOW PARAMETER parallel_force_local,若返回TRUE,必须ALTER SESSION SET parallel_force_local = FALSE - 优化器估算行数过小:统计信息陈旧、
WHERE含SYSDATE或未声明DETERMINISTIC的函数,都会导致降级为串行
为什么执行计划里只有Q000,没有Q101/Q201?
出现这种情况,说明并行根本没启动,不是Hint问题,而是优化器决策层面放弃了并行:
- 先看真实执行计划:
EXPLAIN PLAN FOR SELECT /*+ parallel(t, 8) */ * FROM t WHERE ...;,再SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY) - 重点盯
IN-OUT列:出现P->P才表示跨实例并行激活;若为P->S,说明某步被强制串行化(比如ORDER BY引发全局排序) - 检查谓词是否可并行:
ROWNUM、USER、未加DETERMINISTIC的自定义函数,都会让并行退化
为什么Direct Path Read没触发?
全表扫描没走direct path read,核心是没绕过Buffer Cache:
- 默认阈值由
_small_table_threshold控制(约Buffer Cache的2%),查法:SELECT ksppinm, ksppstvl FROM x$ksppi a, x$ksppcv b WHERE a.indx = b.indx AND ksppinm = '_small_table_threshold' - 即使表远大于阈值,若Buffer Cache里已有大量该表块(比如刚做过串行查询),Oracle仍会优先走缓存路径
- 临时强制直读:
ALTER SESSION SET "_serial_direct_read" = ALWAYS,或在19c+用/*+ direct */Hint
真正难调的不是怎么写Hint,而是理解Oracle 19c在分区裁剪、并行决策、RAC分发这三层上的耦合逻辑——一个环节卡住,整个并行链就断了。尤其要注意parallel_force_local这种默认关不掉的开关,以及单分区裁剪这个“看起来合理、实则拦路”的默认行为。











