I was tuning a parallel query and was a little surprised to find that an outline hint from EXPLAIN PLAN and dbms_xplan.display did not contain a PARALLEL hint. So, a query I was testing did not run in parallel with the outline hint. I had to add the PARALLEL hint. It is surprising because I think of an outline hint as a full set of hints.
I built a testcase to demonstrate this. Here is a zip of its script and output on a 19c database: blogparalleloutlinehints.zip.
I created a small test table and got the outline for the plan of a select statement with a parallel hint:
drop table test;
create table test noparallel as select * from dba_tables;
explain plan into plan_table for
select /*+ parallel(test,8) */ sum(blocks) from test;
set markup html preformat on
select * from table(dbms_xplan.display('PLAN_TABLE',NULL,'ADVANCED'));
The outline hint looks like this:
/*+
BEGIN_OUTLINE_DATA
FULL(@"SEL$1" "TEST"@"SEL$1")
OUTLINE_LEAF(@"SEL$1")
ALL_ROWS
DB_VERSION('19.1.0')
OPTIMIZER_FEATURES_ENABLE('19.1.0')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/
Notice that it just has a FULL hint and nothing about running the query in parallel.
Next, I ran the query with the outline hint but without any parallel hint like this:
select /*+
BEGIN_OUTLINE_DATA
FULL(@"SEL$1" "TEST"@"SEL$1")
OUTLINE_LEAF(@"SEL$1")
ALL_ROWS
DB_VERSION('19.1.0')
OPTIMIZER_FEATURES_ENABLE('19.1.0')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/ sum(blocks) from test;
It ran with a serial (non-parallel) plan:
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 27 (100)| |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
| 2 | TABLE ACCESS FULL| TEST | 1785 | 5355 | 27 (0)| 00:00:01 |
---------------------------------------------------------------------------
Then I ran the query with both a parallel hint and the same outline hint:
select /*+ parallel(test,8)
BEGIN_OUTLINE_DATA
FULL(@"SEL$1" "TEST"@"SEL$1")
OUTLINE_LEAF(@"SEL$1")
ALL_ROWS
DB_VERSION('19.1.0')
OPTIMIZER_FEATURES_ENABLE('19.1.0')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/ sum(blocks) from test;
It ran the desired parallel plan:
-------------------------------------------...---------------------
| Id | Operation | Name |...|IN-OUT| PQ Distrib |
-------------------------------------------...---------------------
| 0 | SELECT STATEMENT | |...| | |
| 1 | SORT AGGREGATE | |...| | |
| 2 | PX COORDINATOR | |...| | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 |...| P->S | QC (RAND) |
| 4 | SORT AGGREGATE | |...| PCWP | |
| 5 | PX BLOCK ITERATOR | |...| PCWC | |
|* 6 | TABLE ACCESS FULL| TEST |...| PCWP | |
-------------------------------------------...---------------------
In other tuning situations with plans that did not execute in parallel the outline hints from dbms_xplan.display_cursor did a great job of capturing all the details of the plan. But when extracting an outline hint from a query that has a parallel hint in it, I needed both the outline hint and the parallel hint to get the same plan.
Bobby