跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何优化Oracle中的大表全扫描_在PL/SQL中使用Parallel Hint并行。

/+ PARALLEL /提示不生效的根本原因在于“能不能用”和“值不值得用”,需满足表并行属性启用、会话并行模式开启、别名严格匹配、DOP合理等条件,否则优化器会降级为串行。 直接加
/*+ parallel */
不一定生效,甚至可能被优化器无视——关键不在“写没写”,而在“能不能用”和“值不值得用”。 为什么
/*+ PARALLEL */
提示没走并行 常见现象是写了提示但执行计划里仍是
TABLE ACCESS FULL
,没有出现
PX
相关操作(如
PX COORDINATOR
、
PX SEND QC
)。根本原因不是语法错,而是以下任一条件不满足: 表所在表空间未启用
PARALLEL
属性(
ALTER TABLE t1 PARALLEL 4
或建表时指定) 会话级未开启并行 DML/DDL 模式(
ALTER SESSION ENABLE PARALLEL DML
仅对 DML 有效;查询需确保
PARALLEL_DEGREE_POLICY
非
MANUAL
,或显式设
PARALLEL_FORCE_LOCAL=FALSE
) 目标表被
NOLOGGING
或
READ ONLY
限制,或存在未提交的事务锁住部分分区 优化器估算的并行成本高于串行,尤其当
_parallel_syspls_auto
隐含参数关闭且未配
DEGREE
值时,
/*+ PARALLEL */
默认行为可能退化为串行
/*+ PARALLEL(t, 4) */
中的表别名必须严格匹配 提示里的表别名不是可选的“方便写法”,而是强制绑定对象。如果 FROM 子句中用了别名
e
,提示就必须写
/*+ PARALLEL(e, 4) */
;写成
/*+ PARALLEL(emp, 4) */
或漏掉别名,Oracle 就无法关联到实际访问路径。 复合查询(UNION / WITH)中,每个子句的表都要单独加提示,不能只在最外层加 视图内嵌套表时,提示必须作用于视图定义中的原始表名或其别名,而非视图名本身 使用同义词时,提示中必须用同义词指向的基表名,而不是同义词名(除非该同义词是 PUBLIC 且已解析) 并行度(DOP)设太高反而拖慢查询 盲目设
DEGREE=32
不等于快 32 倍。真实收益受 I/O 子系统吞吐、CPU 核心数、PGA 内存、以及数据块物理连续性共同制约。 oracle知识库 oracle知识库下载 下载 当表高水位线(HWM)碎裂严重(比如反复 DELETE + INSERT 后),并行进程会大量读空块,逻辑读暴涨,
db file scattered read
等待激增 DOP 超过
CPU_COUNT × 2
后,进程调度开销常超过并行收益,尤其在 OLTP 类混合负载中 小表(行数
_small_table_threshold
默认约 2% buffer cache)即使加并行,也大概率被降级为串行扫描——这是 Oracle 内部保护机制,不是 bug 真正要检查的三件事,比写提示更重要 很多性能问题卡在前置条件上,而不是提示本身。动手前先确认: 查
V$PQ_SESSTAT
和
V$PX_SESSION
,看当前会话是否真有并行 slave 在运行,别只信执行计划里的文字 用
SELECT DEGREE, INSTANCES FROM USER_TABLES WHERE TABLE_NAME = 'T1'
确认表级并行属性是否生效(
DEFAULT
不等于“自动启用”) 跑一次
EXPLAIN PLAN FOR SELECT /*+ PARALLEL(t, 4) */ * FROM t1 WHERE ...
,再
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)
,重点看
IN-OUT
列是否为
P->P
或
P->S
,否则说明并行流水线根本没搭起来 并行不是银弹。它放大 I/O 能力的同时,也放大了碎片、锁争用和内存压力。真正难的不是让语句“看起来并行”,而是让数据、配置和查询逻辑一起配合得上。

相关文章