Oracle 提示PARALLEL (AUTO)
似乎阻止了并行执行。以下是在 12c 开发服务器上,但我们在 19c 服务器上看到了类似的行为。 PARALLEL
产生并行执行,但PARALLEL (AUTO)
没有。为什么不?
drop table ParallelAuto;
create table ParallelAuto as
select level id from dual connect by level <= 1
;
select pdml_enabled, pdml_status, pddl_status, pq_status
from v$session
where sid = (select sid from v$mystat where rownum = 1)
;
+--------------+--------------+-------------+------ -----+ | PDML_ENABLED | PDML_状态 | PDDL_状态 | PQ_STATUS | +--------------+--------------+-------------+------ -----+ | 否 | 已禁用 | 启用 | 启用 | +--------------+--------------+-------------+------ -----+
alter session ENABLE PARALLEL DML;
select pdml_enabled, pdml_status, pddl_status, pq_status
from v$session
where sid = (select sid from v$mystat where rownum = 1)
;
+--------------+--------------+-------------+------ -----+ | PDML_ENABLED | PDML_状态 | PDDL_状态 | PQ_STATUS | +--------------+--------------+-------------+------ -----+ | 是 | 启用 | 启用 | 启用 | +--------------+--------------+-------------+------ -----+
启用 PDML。
以下是%parallel%
供参考的参数。
select name, value, isdefault, ismodified, isadjusted
from v$parameter
where name like '%parallel%'
;
+---------------------------------+--------+------ -----+------------+------------+ | 姓名 | 价值 | 设置默认 | 改装 | 调整 | +---------------------------------+--------+------ -----+------------+------------+ | 并行服务器 | 错误 | 真的 | 错误 | 错误 | | 并行服务器实例 | 1 | 真的 | 错误 | 错误 | | recovery_parallelism | 0 | 真的 | 错误 | 错误 | | fast_start_parallel_rollback | 低 | 真的 | 错误 | 错误 | | 并行最小百分比 | 0 | 真的 | 错误 | 错误 | | 并行最小服务器 | 32 | 真的 | 错误 | 错误 | | 并行最大服务器 | 320 | 真的 | 错误 | 错误 | | 并行实例组 | | 真的 | 错误 | 错误 | | 并行执行消息大小 | 16384 | 真的 | 错误 | 错误 | | parallel_degree_policy | 手册 | 真的 | 错误 | 错误 | | 并行自适应多用户 | 真的 | 真的 | 错误 | 错误 | | parallel_threads_per_cpu | 2 | 真的 | 错误 | 错误 | | 并行自动调整 | 错误 | 真的 | 错误 | 错误 | | parallel_io_cap_enabled | 错误 | 真的 | 错误 | 错误 | | parallel_min_time_threshold | 自动 | 真的 | 错误 | 错误 | | parallel_degree_limit | 中央处理器 | 真的 | 错误 | 错误 | | parallel_force_local | 错误 | 真的 | 错误 | 错误 | | 并行服务器目标 | 128 | 真的 | 错误 | 错误 | | parallel_degree_level | 100 | 真的 | 错误 | 错误 | +---------------------------------+--------+------ -----+------------+------------+
解释这个UPDATE
DML 表明我们确实得到了并行执行。
update /*+ ENABLE_PARALLEL_DML PARALLEL */ ParallelAuto set id = 2;
-------------------------------------------------- -------------------------------------------------- --------------- | 身份证 | 操作 | 姓名 | 行 | 字节 | 成本 (%CPU)| 时间 | TQ |进出| PQ 分配 | -------------------------------------------------- -------------------------------------------------- --------------- | 0 | 更新声明 | | 1 | 13 | 3 (0)| 00:00:01 | | | | | 1 | PX 协调员 | | | | | | | | | | 2 | PX 发送 QC(随机) | :TQ10000 | 1 | 13 | 3 (0)| 00:00:01 | Q1,00 | P->S | 质量控制 (兰德) | | 3 | 更新 | 平行汽车 | | | | | Q1,00 | PCWP | | | 4 | PX 块迭代器 | | 1 | 13 | 3 (0)| 00:00:01 | Q1,00 | PCWC | | | 5 | 表访问已满| 平行汽车 | 1 | 13 | 3 (0)| 00:00:01 | Q1,00 | PCWP | | -------------------------------------------------- -------------------------------------------------- --------------- ... 笔记 - 使用的动态统计:动态采样(级别=2) - 自动 DOP:计算的并行度为 2
但是,当使用PARALLEL (AUTO)
提示时,我们不再接收并行执行。
update /*+ ENABLE_PARALLEL_DML PARALLEL (AUTO) */ ParallelAuto set id = 3;
-------------------------------------------------- --------------------------------- | 身份证 | 操作 | 姓名 | 行 | 字节 | 成本 (%CPU)| 时间 | -------------------------------------------------- --------------------------------- | 0 | 更新声明 | | 1 | 13 | 5 (0)| 00:00:01 | | 1 | 更新 | 平行汽车 | | | | | | 2 | 表访问已满| 平行汽车 | 1 | 13 | 5 (0)| 00:00:01 | -------------------------------------------------- --------------------------------- ... 笔记 - 使用的动态统计:动态采样(级别=2) - 自动 DOP:计算的并行度为 1,因为并行阈值 - PDML 被禁用,因为对象没有用并行子句修饰
只是为了确认它不是PARALLEL_DEGREE_POLICY
让我们把它改成不是MANUAL
。
alter session set parallel_degree_policy = AUTO;
select name, value, isdefault, ismodified, isadjusted
from v$parameter
where name like 'parallel_degree_policy'
;
+---------------------------------+--------+------ -----+------------+------------+ | 姓名 | 价值 | 设置默认 | 改装 | 调整 | +---------------------------------+--------+------ -----+------------+------------+ | parallel_degree_policy | 自动 | 真的 | 修改 | 错误 | +---------------------------------+--------+------ -----+------------+------------+
update /*+ ENABLE_PARALLEL_DML PARALLEL */ ParallelAuto set id = 3;
笔记 - 使用的动态统计:动态采样(级别=2) - 自动 DOP:计算的并行度为 2
update /*+ ENABLE_PARALLEL_DML PARALLEL (AUTO) */ ParallelAuto set id = 3;
笔记 - 使用的动态统计:动态采样(级别=2) - 自动 DOP:计算的并行度为 1,因为并行阈值 - PDML 被禁用,因为对象没有用并行子句修饰
结果相同。
即使我们从语句中删除 PDML 方面,SELECT
(Parallel Query - PQ) 也会出现令人惊讶的结果。
select /*+ PARALLEL */ * from ParallelAuto;
笔记 - 使用的动态统计:动态采样(级别=2) - 自动 DOP:计算的并行度为 2
select /*+ PARALLEL (AUTO) */ * from ParallelAuto;
笔记 - 使用的动态统计:动态采样(级别=2) - 自动 DOP:计算的并行度为 1,因为并行阈值
此非生产服务器上的活动非常有限。
这种行为PARALLEL (AUTO)
似乎与文档相矛盾(参考下文)。
Oracle SQL 数据库参考 | PARALLEL_DEGREE_POLICY
注意:如果在 SQL 语句级别使用 PARALLEL 提示,则无论 PARALLEL_DEGREE_POLICY 的值如何,都将启用自动并行度。
Oracle SQL 参考指南 | 评论 | 提示
此提示会覆盖 PARALLEL_DEGREE_POLICY 初始化参数的值。它适用于语句的 SELECT、INSERT、MERGE、UPDATE 和 DELETE 部分,以及表扫描部分。如果违反了任何并行限制,则忽略该提示。
12c
PARALLEL:语句始终并行运行,数据库计算并行度,可以为 2 或更大。
PARALLEL (AUTO):数据库计算并行度,可以为 1 或更大。如果计算出的并行度为 1,则语句串行运行。
PARALLEL (MANUAL):优化器被迫使用语句中对象的并行设置。
19c/21c
PARALLEL:该语句导致的并行度等于或大于计算的并行度,除非并行度对于最低成本计划不可行。当并行性不可行时,该语句将串行运行。
PARALLEL (AUTO):该语句导致的并行度等于或大于计算的并行度,除非并行度对于最低成本计划不可行。当并行性不可行时,该语句将串行运行。
PARALLEL (MANUAL):优化器被迫使用语句中对象的并行设置。
这里发生了什么?提前致谢。