查询不使用指定的并行度
Query does not use specified parallel degree
在我的 Oracle 12c 数据库中,我希望在不使用提示的情况下以并行度 2 执行语句。 注意:这是一个示例 table,因此在成本或时间上没有改善。
并行度为 1 的执行计划
PLAN_TABLE_OUTPUT
-----------------
Plan hash value: 2671887276
-----------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------
| 0 | SELECT STATEMENT | | 1 | 674 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EVENT | 1 | 674 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EVENT_PK | 1 | | 1 (0)| 00:00:01 |
--------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EVENT_PK"='zjmtzhjrth')
Note
-----
- automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
带提示的执行计划/*+parallel(2) */
DoP 工作正常
PLAN_TABLE_OUTPUT
---------------
Plan hash value: 2851389777
----------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
---------------
| 0 | SELECT STATEMENT | | 1 | 674 | 2 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 1 | 674 | 2 (0)| 00:00:01 | Q1,01 | P->S | QC (RAND) |
| 3 | TABLE ACCESS BY INDEX ROWID | EVENT | 1 | 674 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
| 4 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 5 | PX RECEIVE | | 1 | | 1 (0)| 00:00:01 | Q1,01 | PCWP | |
| 6 | PX SEND HASH (BLOCK ADDRESS)| :TQ10000 | 1 | | 1 (0)| 00:00:01 | Q1,00 | S->P | HASH (BLOCK|
| 7 | PX SELECTOR | | | | | | Q1,00 | SCWC | |
|* 8 | INDEX UNIQUE SCAN | EVENT_PK | 1 | | 1 (0)| 00:00:01 | Q1,00 | SCWP | |
--------------------
Predicate Information (identified by operation id):
---------------------------------------------------
8 - access("EVENT_PK"='zjmtzhjrth')
Note
-----
- Degree of Parallelism is 2 because of hint
然后我执行了下面的语句
alter system set parallel_degree_policy=MANUAL;
alter table event parallel 2;
但是当我在没有提示的情况下执行语句时,它没有使用并行性。它甚至没有给我关于执行计划中 DoP 的注释。
PLAN_TABLE_OUTPUT
----------------
Plan hash value: 2671887276
-----------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 674 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EVENT | 1 | 674 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EVENT_PK | 1 | | 1 (0)| 00:00:01 |
-------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EVENT_PK"='zjmtzhjrth')
谁能告诉我为什么这不起作用?
关于评论中的问题:
PARALLEL_DEGREE_LIMIT=CPU
当我将 PARALLEL_DEGREE_POLICY
设置回 AUTO
时,它再次给我提示:
Note
-----
- automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
我为测试发布的声明是
select * from event where event_pk = 'swdfklwe';
根据 Cyrille 的评论,我尝试了选定列和 where 子句中列的所有组合。当使用索引唯一扫描时,该语句不会使用 DoP 2。
select event_pk, result form event where event_pk = 'swdfklwe'
select event_pk form event where event_pk = 'swdfklwe'
select event_pk, result form event where event_pk = 'swdfklwe' and result = 0
select event_pk form event where event_pk = 'swdfklwe' and result = 0
我这边的效果和预期的一样:
SQL> create table t1 (id number);
Table created.
SQL> alter table t1 parallel 2;
Table altered.
SQL> explain plan for select * from t1;
Explained.
SQL> @?/rdbms/admin/utlxpls
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2494645258
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |
| 1 | PX COORDINATOR | | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 1 | 13 | 2 (0)| 00:00:01 |
| 3 | PX BLOCK ITERATOR | | 1 | 13 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| T1 | 1 | 13 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 2 because of table property
这是我的参数(所有默认值)
SQL> show parameter parallel
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
containers_parallel_degree integer 65535
fast_start_parallel_rollback string LOW
parallel_adaptive_multi_user boolean FALSE
parallel_degree_limit string CPU
parallel_degree_policy string MANUAL
parallel_execution_message_size integer 16384
parallel_force_local boolean FALSE
parallel_instance_group string
parallel_max_servers integer 40
parallel_min_percent integer 0
parallel_min_servers integer 4
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
parallel_min_time_threshold string AUTO
parallel_servers_target integer 16
parallel_threads_per_cpu integer 2
recovery_parallelism integer 0
SQL>
并行执行是为了加快遍历大量记录的查询。它将要搜索的总记录集分成更小的集合,并同时处理多个集合。这会增加系统资源消耗 - 主要是 CPU - 以减少总响应时间。
您的 table 在搜索的列上有唯一索引。所以只能有一条记录匹配'EVENT_PK"='zjmtzhjrth'
。并行性无法使其更快。
优化器选择了最有效的访问路径来检索一行。很高兴它有。
为什么不会
在我的 Oracle 12c 数据库中,我希望在不使用提示的情况下以并行度 2 执行语句。 注意:这是一个示例 table,因此在成本或时间上没有改善。
并行度为 1 的执行计划
PLAN_TABLE_OUTPUT
-----------------
Plan hash value: 2671887276
-----------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------
| 0 | SELECT STATEMENT | | 1 | 674 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EVENT | 1 | 674 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EVENT_PK | 1 | | 1 (0)| 00:00:01 |
--------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EVENT_PK"='zjmtzhjrth')
Note
-----
- automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
带提示的执行计划/*+parallel(2) */
DoP 工作正常
PLAN_TABLE_OUTPUT
---------------
Plan hash value: 2851389777
----------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
---------------
| 0 | SELECT STATEMENT | | 1 | 674 | 2 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 1 | 674 | 2 (0)| 00:00:01 | Q1,01 | P->S | QC (RAND) |
| 3 | TABLE ACCESS BY INDEX ROWID | EVENT | 1 | 674 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
| 4 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 5 | PX RECEIVE | | 1 | | 1 (0)| 00:00:01 | Q1,01 | PCWP | |
| 6 | PX SEND HASH (BLOCK ADDRESS)| :TQ10000 | 1 | | 1 (0)| 00:00:01 | Q1,00 | S->P | HASH (BLOCK|
| 7 | PX SELECTOR | | | | | | Q1,00 | SCWC | |
|* 8 | INDEX UNIQUE SCAN | EVENT_PK | 1 | | 1 (0)| 00:00:01 | Q1,00 | SCWP | |
--------------------
Predicate Information (identified by operation id):
---------------------------------------------------
8 - access("EVENT_PK"='zjmtzhjrth')
Note
-----
- Degree of Parallelism is 2 because of hint
然后我执行了下面的语句
alter system set parallel_degree_policy=MANUAL;
alter table event parallel 2;
但是当我在没有提示的情况下执行语句时,它没有使用并行性。它甚至没有给我关于执行计划中 DoP 的注释。
PLAN_TABLE_OUTPUT
----------------
Plan hash value: 2671887276
-----------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 674 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EVENT | 1 | 674 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EVENT_PK | 1 | | 1 (0)| 00:00:01 |
-------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EVENT_PK"='zjmtzhjrth')
谁能告诉我为什么这不起作用?
关于评论中的问题:
PARALLEL_DEGREE_LIMIT=CPU
当我将 PARALLEL_DEGREE_POLICY
设置回 AUTO
时,它再次给我提示:
Note
-----
- automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
我为测试发布的声明是
select * from event where event_pk = 'swdfklwe';
根据 Cyrille 的评论,我尝试了选定列和 where 子句中列的所有组合。当使用索引唯一扫描时,该语句不会使用 DoP 2。
select event_pk, result form event where event_pk = 'swdfklwe'
select event_pk form event where event_pk = 'swdfklwe'
select event_pk, result form event where event_pk = 'swdfklwe' and result = 0
select event_pk form event where event_pk = 'swdfklwe' and result = 0
我这边的效果和预期的一样:
SQL> create table t1 (id number);
Table created.
SQL> alter table t1 parallel 2;
Table altered.
SQL> explain plan for select * from t1;
Explained.
SQL> @?/rdbms/admin/utlxpls
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2494645258
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |
| 1 | PX COORDINATOR | | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 1 | 13 | 2 (0)| 00:00:01 |
| 3 | PX BLOCK ITERATOR | | 1 | 13 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| T1 | 1 | 13 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 2 because of table property
这是我的参数(所有默认值)
SQL> show parameter parallel
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
containers_parallel_degree integer 65535
fast_start_parallel_rollback string LOW
parallel_adaptive_multi_user boolean FALSE
parallel_degree_limit string CPU
parallel_degree_policy string MANUAL
parallel_execution_message_size integer 16384
parallel_force_local boolean FALSE
parallel_instance_group string
parallel_max_servers integer 40
parallel_min_percent integer 0
parallel_min_servers integer 4
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
parallel_min_time_threshold string AUTO
parallel_servers_target integer 16
parallel_threads_per_cpu integer 2
recovery_parallelism integer 0
SQL>
并行执行是为了加快遍历大量记录的查询。它将要搜索的总记录集分成更小的集合,并同时处理多个集合。这会增加系统资源消耗 - 主要是 CPU - 以减少总响应时间。
您的 table 在搜索的列上有唯一索引。所以只能有一条记录匹配'EVENT_PK"='zjmtzhjrth'
。并行性无法使其更快。
优化器选择了最有效的访问路径来检索一行。很高兴它有。
为什么不会