您没有很好地解释您的数据模型,所以让我解释一下有关 Oracle 并行执行的不同可能性。在插入/选择语句的情况下,有两个操作可能会或可能不会并行运行。一个是选择,另一个是插入。
测试用例表
SQL> create table t ( id number , c1 varchar2(130) ) ;
Table created.
SQL> create table x as select object_id , object_name from dba_objects ;
Table created.
SQL> select count(*) from x ;
COUNT(*)
----------
172514
场景 1
表没有并行定义,没有通知提示,也没有启用更改会话并行。插入和选择将以串行模式运行。
SQL> explain plan for
2 insert into t select * from x ;
Explained.
SQL> select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2941724873
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 194K| 14M| 172 (1)| 00:00:01 |
| 1 | LOAD TABLE CONVENTIONAL | T | | | | |
| 2 | TABLE ACCESS FULL | X | 194K| 14M| 172 (1)| 00:00:01 |
---------------------------------------------------------------------------------
场景 2
insert语句中使用了提示parallel,表没有parallel定义,也没有启用alter session。查询将以串行模式运行,包括插入和选择。
SQL> explain plan for insert /*+parallel(t,10)*/ into t select * from x ;
Explained.
SQL> select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------Plan hash value: 2941724873
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 194K| 14M| 172 (1)| 00:00:01 |
| 1 | LOAD TABLE CONVENTIONAL | T | | | | |
| 2 | TABLE ACCESS FULL | X | 194K| 14M| 172 (1)| 00:00:01 |
---------------------------------------------------------------------------------
场景 3
提示用于选择和插入。任何表中都没有并行定义,也没有使用更改会话。插入将以串行模式运行,但选择将并行运行。 (查看说明计划末尾的注释)
SQL> explain plan for insert /*+parallel(t,10)*/ into t select /*+parallel(x,10)*/ * from x ;
Explained.
SQL> select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
----------------------------------------
Plan hash value: 3828196258
--------------------------------------------------------------------------------------
----------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 194K| 14M| 172 (1)| 00:00:01 | | | |
| 1 | LOAD TABLE CONVENTIONAL | T | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 194K| 14M| 172 (1)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 4 | PX BLOCK ITERATOR | | 194K| 14M| 172 (1)| 00:00:01 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL | X | 194K| 14M| 172 (1)| 00:00:01 | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 10 because of table property
- PDML is disabled in current session
正如您在上面的解释计划中看到的那样,由于提示,选择正在并行运行。原因是,默认情况下,enable parallel query 是为每个会话设置的,因此如果您在 select 中使用并行提示,则 select 将并行运行。
场景 4
insert 和 select 都使用提示,但这次我们启用了并行 dml。这些表没有并行定义。插入将与选择一样并行运行。查看解释计划的注释。
SQL> alter session enable parallel dml ;
Session altered.
SQL> explain plan for insert /*+parallel(t,10)*/ into t select /*+parallel(x,10)*/ * from x ;
Explained.
SQL> select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2234885790
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 194K| 14M| 19 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 194K| 14M| 19 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 3 | LOAD AS SELECT (HYBRID TSM/HWMB)| T | | | | | Q1,00 | PCWP | |
| 4 | PX BLOCK ITERATOR | | 194K| 14M| 19 (0)| 00:00:01 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL | X | 194K| 14M| 19 (0)| 00:00:01 | Q1,00 | PCWP | |
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 10 because of table property
如果在启用并行 dml 的情况下对插入操作使用提示并行,则插入将作为直接路径语句运行,而不是作为常规插入。请记住,直接路径操作是 table-lock ,因此在这种情况下,该表将被锁定以进行任何其他 dml 操作,直到事务提交为止。
场景 5
您还可以更改表的并行属性,然后您不需要使用任何提示。仅启用并行 dml。
SQL> alter table t parallel 8 ;
Table altered.
SQL> alter table x parallel 8 ;
Table altered.
SQL> alter session enable parallel dml ;
Session altered.
SQL> explain plan for insert into t select * from x ;
Explained.
SQL> select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------Plan hash value: 2234885790
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 194K| 14M| 24 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 194K| 14M| 24 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 3 | LOAD AS SELECT (HYBRID TSM/HWMB)| T | | | | | Q1,00 | PCWP | |
| 4 | PX BLOCK ITERATOR | | 194K| 14M| 24 (0)| 00:00:01 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL | X | 194K| 14M| 24 (0)| 00:00:01 | Q1,00 | PCWP | |
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 8 because of table property
还要记住一些限制:
- 如果您进行插入的表启用了触发器,则该操作将不会并行运行。
- 如果您希望插入并行运行,则必须始终启用并行 DML。在这种情况下,要么使用提示并行,要么更改表的程度。使用不当的提示不会引发任何错误,只是它们不起作用。
- 如果您并行运行插入/选择,在大多数情况下并行运行这两个操作非常重要,因此每个 QC 的使用者可以共同工作。如果您仅并行运行 select,则 select 的使用者最终将处于空闲状态,同时单个威胁正在运行插入。
- 需要此模式(启用并行 dml),因为并行 DML 和串行 DML 具有不同的锁定、事务和磁盘空间要求,并且默认情况下会话禁用并行 DML。禁用并行 DML 时,即使使用了 PARALLEL 提示,也不会并行执行 DML。
您可以在此处阅读有关并行 dml 限制的更多信息
Restrictions on Parallel DML