并行(自动)Oracle 提示和 PARALLEL_MIN_TIME_THRESHOLD

PARALLEL (AUTO) Oracle Hint and PARALLEL_MIN_TIME_THRESHOLD

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_STATUS | PDDL_STATUS | PQ_STATUS |
+--------------+-------------+-------------+-----------+
| NO           | DISABLED    | ENABLED     | ENABLED   |
+--------------+-------------+-------------+-----------+
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_STATUS | PDDL_STATUS | PQ_STATUS |
+--------------+-------------+-------------+-----------+ 
| YES          | ENABLED     | ENABLED     | ENABLED   |
+--------------+-------------+-------------+-----------+

PDML 已启用。

以下是%parallel%个参数供参考

select name, value, isdefault, ismodified, isadjusted 
  from v$parameter 
  where name like '%parallel%'  
;
+---------------------------------+--------+-----------+------------+------------+
| NAME                            | VALUE  | ISDEFAULT | ISMODIFIED | ISADJUSTED |
+---------------------------------+--------+-----------+------------+------------+
| parallel_server                 | FALSE  | TRUE      | FALSE      | FALSE      |
| parallel_server_instances       | 1      | TRUE      | FALSE      | FALSE      |
| recovery_parallelism            | 0      | TRUE      | FALSE      | FALSE      |
| fast_start_parallel_rollback    | LOW    | TRUE      | FALSE      | FALSE      |
| parallel_min_percent            | 0      | TRUE      | FALSE      | FALSE      |
| parallel_min_servers            | 32     | TRUE      | FALSE      | FALSE      |
| parallel_max_servers            | 320    | TRUE      | FALSE      | FALSE      |
| parallel_instance_group         |        | TRUE      | FALSE      | FALSE      |
| parallel_execution_message_size | 16384  | TRUE      | FALSE      | FALSE      |
| parallel_degree_policy          | MANUAL | TRUE      | FALSE      | FALSE      |
| parallel_adaptive_multi_user    | TRUE   | TRUE      | FALSE      | FALSE      |
| parallel_threads_per_cpu        | 2      | TRUE      | FALSE      | FALSE      |
| parallel_automatic_tuning       | FALSE  | TRUE      | FALSE      | FALSE      |
| parallel_io_cap_enabled         | FALSE  | TRUE      | FALSE      | FALSE      |
| parallel_min_time_threshold     | AUTO   | TRUE      | FALSE      | FALSE      |
| parallel_degree_limit           | CPU    | TRUE      | FALSE      | FALSE      |
| parallel_force_local            | FALSE  | TRUE      | FALSE      | FALSE      |
| parallel_servers_target         | 128    | TRUE      | FALSE      | FALSE      |
| parallel_degree_level           | 100    | TRUE      | FALSE      | FALSE      |
+---------------------------------+--------+-----------+------------+------------+

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

update /*+ ENABLE_PARALLEL_DML PARALLEL */ ParallelAuto set id = 2;

-------------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name         | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |              |     1 |    13 |     3   (0)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR       |              |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM) | :TQ10000     |     1 |    13 |     3   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    UPDATE             | PARALLELAUTO |       |       |            |          |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR |              |     1 |    13 |     3   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL| PARALLELAUTO |     1 |    13 |     3   (0)| 00:00:01 |  Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------
...
Note
   - dynamic statistics used: dynamic sampling (level=2)
   - automatic DOP: Computed Degree of Parallelism is 2

但是,当使用 PARALLEL (AUTO) 提示时,我们不再收到并行执行。

update /*+ ENABLE_PARALLEL_DML PARALLEL (AUTO) */ ParallelAuto set id = 3;

-----------------------------------------------------------------------------------
| Id  | Operation          | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |              |     1 |    13 |     5   (0)| 00:00:01 |
|   1 |  UPDATE            | PARALLELAUTO |       |       |            |          |
|   2 |   TABLE ACCESS FULL| PARALLELAUTO |     1 |    13 |     5   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
...
Note
   - dynamic statistics used: dynamic sampling (level=2)
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
   - PDML disabled because object is not decorated with parallel clause

只是为了确认它不是 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'
;
+---------------------------------+--------+-----------+------------+------------+
| NAME                            | VALUE  | ISDEFAULT | ISMODIFIED | ISADJUSTED |
+---------------------------------+--------+-----------+------------+------------+
| parallel_degree_policy          | AUTO   | TRUE      | MODIFIED   | FALSE      |
+---------------------------------+--------+-----------+------------+------------+
update /*+ ENABLE_PARALLEL_DML PARALLEL */ ParallelAuto set id = 3;
Note
   - dynamic statistics used: dynamic sampling (level=2)
   - automatic DOP: Computed Degree of Parallelism is 2
update /*+ ENABLE_PARALLEL_DML PARALLEL (AUTO) */ ParallelAuto set id = 3;
Note
   - dynamic statistics used: dynamic sampling (level=2)
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
   - PDML disabled because object is not decorated with parallel clause

相同的结果。

即使我们从语句中删除 PDML 方面,SELECT(并行查询 - PQ)也会出现令人惊讶的结果。

select /*+ PARALLEL */ * from ParallelAuto;
Note
   - dynamic statistics used: dynamic sampling (level=2)
   - automatic DOP: Computed Degree of Parallelism is 2
select /*+ PARALLEL (AUTO) */ * from ParallelAuto;
Note
   - dynamic statistics used: dynamic sampling (level=2)
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold

在此非生产服务器上 activity 非常有限。

PARALLEL (AUTO) 的这种行为似乎与文档(在下面引用)相矛盾。

Oracle SQL 数据库参考 | PARALLEL_DEGREE_POLICY

Note:Automatic degree of parallelism will be enabled regardless of the value of PARALLEL_DEGREE_POLICY if a PARALLEL hint is used at the SQL statement level.

Oracle SQL 参考指南 |评论 |提示

This hint overrides the value of the PARALLEL_DEGREE_POLICY initialization parameter. It applies to the SELECT, INSERT, MERGE, UPDATE, and DELETE portions of a statement, as well as to the table scan portion. If any parallel restrictions are violated, then the hint is ignored.

12c

PARALLEL: The statement always is run parallel, and the database computes the degree of parallelism, which can be 2 or greater.
PARALLEL (AUTO): The database computes the degree of parallelism, which can be 1 or greater. If the computed degree of parallelism is 1, then the statement runs serially.
PARALLEL (MANUAL): The optimizer is forced to use the parallel settings of the objects in the statement.

19c/21c

PARALLEL: The statement results in a degree of parallelism equal to or greater than the computed degree of parallelism, except when parallelism is not feasible for the lowest cost plan. When parallelism is is not feasible, the statement runs serially.
PARALLEL (AUTO): The statement results in a degree of parallelism that is equal to or greater than the computed degree of parallelism, except when parallelism is not feasible for the lowest cost plan. When parallelism is is not feasible, the statement runs serially.
PARALLEL (MANUAL): The optimizer is forced to use the parallel settings of the objects in the statement.

这是怎么回事?提前致谢。

如果估计的 运行 时间小于 PARALLEL_MIN_TIME_THRESHOLD

PARALLEL(AUTO) 将不会启用并行性,默认为 10 秒(容易混淆地称为“AUTO”)。这种行为可能是一件好事,因为并行性会增加很多开销,并且并行性可能会不公平地使用大量资源来使快速语句只稍微快一点。

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

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

或者,您可以在会话或系统级别修改 PARALLEL_MIN_TIME_THRESHOLD。尽管由于您的测试 table 只有一行,因此可能没有足够低的值来触发并行性而不创建假行数。

alter session set parallel_min_time_threshold = 1;