drop table t1 purge;
drop table t2 purge;
create table t1 as select * from all_objects;
create table t2 as select * from all_objects;
exec dbms_stats.gather_table_stats(user,'T1');
exec dbms_stats.gather_table_stats(user,'T2');
without parallel dml enabled in a session, if you have a MERGE statement with parallel hints.
a) the "read" portion of the queries will be done in parallel - you can see that step from this Explain plan as "PX BLOCK ITERATOR" before full scan of T1 and T2.
b) the write portion of the queries are NOT done in parallel - since the MERGE operation is above the "PX COORDINATOR"
so each parallel slaves spanned by the coordinator, will scan the T1 and T2, join them in parallel and produce those results to coordinator, and coordinator will take care of modifications (in serial phase)
demo@ORA11G> explain plan for
2 merge /*+ parallel(t1,2) parallel(t2,2) */ into t1 using t2
3 on (t1.object_id = t2.object_id)
4 when matched then
5 update set t1.object_name = t2.object_name ;
Explained.
demo@ORA11G> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1241486182
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 75730 | 3180K| 337 (1)| 00:00:05 | | | |
| 1 | MERGE | T1 | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10001 | 75730 | 14M| 337 (1)| 00:00:05 | Q1,01 | P->S | QC (RAND) |
| 4 | VIEW | | | | | | Q1,01 | PCWP | |
|* 5 | HASH JOIN | | 75730 | 14M| 337 (1)| 00:00:05 | Q1,01 | PCWP | |
| 6 | PX BLOCK ITERATOR | | 75731 | 7247K| 168 (0)| 00:00:03 | Q1,01 | PCWC | |
| 7 | TABLE ACCESS FULL | T2 | 75731 | 7247K| 168 (0)| 00:00:03 | Q1,01 | PCWP | |
| 8 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 9 | PX RECEIVE | | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,01 | PCWP | |
| 10 | PX SEND BROADCAST | :TQ10000 | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,00 | P->P | BROADCAST |
| 11 | PX BLOCK ITERATOR | | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,00 | PCWC | |
| 12 | TABLE ACCESS FULL| T1 | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
24 rows selected.
when explicitly requested for "Parallel dml" plan changes like this ( the "MERGE" step in the plan is below the query coordinator PX COORDINATOR)
demo@ORA11G> alter session enable parallel dml;
Session altered.
demo@ORA11G> explain plan for
2 merge /*+ parallel(t1,2) parallel(t2,2) */ into t1 using t2
3 on (t1.object_id = t2.object_id)
4 when matched then
5 update set t1.object_name = t2.object_name ;
Explained.
demo@ORA11G> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 4094314131
-------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 75730 | 3180K| 337 (1)| 00:00:05 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10002 | 75730 | 14M| 337 (1)| 00:00:05 | Q1,02 | P->S | QC (RAND) |
| 3 | MERGE | T1 | | | | | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 75730 | 14M| 337 (1)| 00:00:05 | Q1,02 | PCWP | |
| 5 | PX SEND HYBRID (ROWID PKEY)| :TQ10001 | 75730 | 14M| 337 (1)| 00:00:05 | Q1,01 | P->P | HYBRID (ROW|
| 6 | VIEW | | | | | | Q1,01 | PCWP | |
|* 7 | HASH JOIN | | 75730 | 14M| 337 (1)| 00:00:05 | Q1,01 | PCWP | |
| 8 | PX BLOCK ITERATOR | | 75731 | 7247K| 168 (0)| 00:00:03 | Q1,01 | PCWC | |
| 9 | TABLE ACCESS FULL | T2 | 75731 | 7247K| 168 (0)| 00:00:03 | Q1,01 | PCWP | |
| 10 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 11 | PX RECEIVE | | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,01 | PCWP | |
| 12 | PX SEND BROADCAST | :TQ10000 | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,00 | P->P | BROADCAST |
| 13 | PX BLOCK ITERATOR | | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,00 | PCWC | |
| 14 | TABLE ACCESS FULL | T1 | 75730 | 7247K| 168 (0)| 00:00:03 | Q1,00 | PCWP | |
-------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
26 rows selected.
demo@ORA11G>
with parallel dml enabled in a session, if you have a MERGE statement with parallel hints.
a) the "read" portion of the queries will be done in parallel - you can see that step from this Explain plan as "PX BLOCK ITERATOR" before full scan of T1 and T2.
b) the write portion of the queries are done in parallel - since the MERGE operation is now below the "PX COORDINATOR"
When you move into 12c, the explain plan provides information in the "notes" section (about the Parallel dml is not enabled).
demo@ORA12C> create table t1 as select * from all_objects;
Table created.
demo@ORA12C> create table t2 as select * from all_objects;
Table created.
demo@ORA12C> explain plan for
2 merge /*+ parallel(t1,2) parallel(t2,2) */ into t1 using t2
3 on (t1.object_id = t2.object_id)
4 when matched then
5 update set t1.object_name = t2.object_name ;
Explained.
demo@ORA12C> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------
Plan hash value: 1303478760
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 60714 | 6166K| 677 (1)| 00:00:01 | | | |
| 1 | MERGE | T1 | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10001 | 60714 | 15M| 677 (1)| 00:00:01 | Q1,01 | P->S | QC (RAND) |
| 4 | VIEW | | | | | | Q1,01 | PCWP | |
|* 5 | HASH JOIN | | 60714 | 15M| 677 (1)| 00:00:01 | Q1,01 | PCWP | |
| 6 | PX RECEIVE | | 60714 | 8122K| 338 (1)| 00:00:01 | Q1,01 | PCWP | |
| 7 | PX SEND BROADCAST | :TQ10000 | 60714 | 8122K| 338 (1)| 00:00:01 | Q1,00 | P->P | BROADCAST |
| 8 | PX BLOCK ITERATOR | | 60714 | 8122K| 338 (1)| 00:00:01 | Q1,00 | PCWC | |
| 9 | TABLE ACCESS FULL| T1 | 60714 | 8122K| 338 (1)| 00:00:01 | Q1,00 | PCWP | |
| 10 | PX BLOCK ITERATOR | | 60715 | 8123K| 338 (1)| 00:00:01 | Q1,01 | PCWC | |
| 11 | TABLE ACCESS FULL | T2 | 60715 | 8123K| 338 (1)| 00:00:01 | Q1,01 | PCWP | |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
Note
-----
- Degree of Parallelism is 2 because of table property
- PDML is disabled in current session
28 rows selected.
Also we have a new hint available in 12c "enable_parallel_dml" that helps you to enable the parallel dml at statement level.
demo@ORA12C> conn demo/demo@ora12c
Connected.
demo@ORA12C> explain plan for
2 merge /*+ enable_parallel_dml parallel(t1,2) parallel(t2,2) */ into t1 using t2
3 on (t1.object_id = t2.object_id)
4 when matched then
5 update set t1.object_name = t2.object_name ;
Explained.
demo@ORA12C> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1850178028
---------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 60714 | 6166K| 376 (1)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10002 | 60714 | 15M| 376 (1)| 00:00:01 | Q1,02 | P->S | QC (RAND) |
| 3 | MERGE | T1 | | | | | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 60714 | 15M| 376 (1)| 00:00:01 | Q1,02 | PCWP | |
| 5 | PX SEND (ROWID RANDOM) | :TQ10001 | 60714 | 15M| 376 (1)| 00:00:01 | Q1,01 | P->P | (ROWID RAND|
| 6 | VIEW | | | | | | Q1,01 | PCWP | |
|* 7 | HASH JOIN BUFFERED | | 60714 | 15M| 376 (1)| 00:00:01 | Q1,01 | PCWP | |
| 8 | PX BLOCK ITERATOR | | 60715 | 8123K| 188 (1)| 00:00:01 | Q1,01 | PCWC | |
| 9 | TABLE ACCESS FULL | T2 | 60715 | 8123K| 188 (1)| 00:00:01 | Q1,01 | PCWP | |
| 10 | PX RECEIVE | | 60714 | 8122K| 188 (1)| 00:00:01 | Q1,01 | PCWP | |
| 11 | PX SEND BROADCAST | :TQ10000 | 60714 | 8122K| 188 (1)| 00:00:01 | Q1,00 | P->P | BROADCAST |
| 12 | PX BLOCK ITERATOR | | 60714 | 8122K| 188 (1)| 00:00:01 | Q1,00 | PCWC | |
| 13 | TABLE ACCESS FULL| T1 | 60714 | 8122K| 188 (1)| 00:00:01 | Q1,00 | PCWP | |
---------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
Note
-----
- Degree of Parallelism is 2 because of table property
29 rows selected.
demo@ORA12C>