1

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 | 真的 | 错误 | 错误 |
+---------------------------------+--------+------ -----+------------+------------+

解释这个UPDATEDML 表明我们确实得到了并行执行。

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):优化器被迫使用语句中对象的并行设置。

这里发生了什么?提前致谢。

4

1 回答 1

1

PARALLEL(AUTO)如果估计的运行时间小于PARALLEL_MIN_TIME_THRESHOLD默认为 10 秒(令人困惑地也称为“AUTO”),则不会启用并行性。这种行为可能是一件好事,因为并行性增加了很多开销,并且并行性可能会不公平地使用大量资源来使快速语句只稍微快一点。

您可以通过创建虚假的行数并让优化器认为 SQL 需要很长时间来测试此行为:

begin
    dbms_stats.set_table_stats(user, 'PARALLELAUTO', numrows => 99999999999);
end;
/

或者,您可以PARALLEL_MIN_TIME_THRESHOLD在会话或系统级别进行修改。尽管由于您的测试表只有一行,但可能没有任何值低到足以触发并行性而不会创建假行数。

alter session set parallel_min_time_threshold = 1;
于 2021-03-08T01:54:02.293 回答