2. About me
OTN yathra 2015 Anju Garg
• More than 12 years of experience in IT Industry
• Sr. Corporate Trainer (Oracle DBA) with Koenig Solutions Ltd.
• Oracle blog : http://oracleinaction.com/
• Email : anjugarg66@gmail.com
• Oracle ACE Associate
• Oracle Certified Expert
2
3. Agenda
• Drawbacks of Pre-12c optimizer
• What's New in 12c?
Adaptive Query Optimization
Adaptive / Dynamic Plans
o Adaptive Parallel Distribution
o Adaptive Joins
Automatic Re-optimization
o SQL Plan Directives
Automatic Query Optimization workflow
• Illustration-I : Adaptive Parallel Distribution
• Illustration-II : Cardinality Feedback in 11g
• Illustration-III : Adaptive joins in 12c
• Illustration-IV : Automatic Re-optimization-I
• Illustration-V : Automatic Re-optimization-II
• Conclusion
• References
• Q & A
OTN yathra 2015 Anju Garg 3
4. Pre-12c optimizer
OTN yathra 2015 Anju Garg 4
• Drawbacks
o Insufficient or stale statistics do not trigger dynamic sampling
with default sampling level of 2.
o SQL has to execute sub-optimally at least once to exploit ACS and
Cardinality Feedback.
o Cardinality feedback / ACS cannot be employed after cursor ages
out.
o In case of parallel queries, incorrect optimizer estimates could
lead to selection of sub-optimal distribution method.
5. What's New in 12c?
Adaptive Query Optimization
• Adaptive / Dynamic plans - Initial execution of a query improved by
making run-time adjustments to execution plan.
– Adaptive Parallel Distribution
– Adaptive Joins
• Automatic Re-optimization - Information gathered during initial
execution is employed to improve subsequent executions of SQL.
– Statistics Feedback
– Dynamic Statistics
– Column group statistics
OTN yathra 2015 Anju Garg 5
6. Adaptive / Dynamic Plans
• The default plan chosen at parse time switched to a better alternative
plan called final plan at run-time.
• Default and final plan must have same starting point.
• How?
– Optimizer stores alternative sub-plans with the cursor.
– Computes threshold cardinality.
– Statistic collectors embedded at critical points in the default
execution plan.
– Switches to an alternative plan, if row count crosses the threshold
• Possible optimizations
– Adaptive Parallel Distribution
– Adaptive joins
OTN yathra 2015 Anju Garg 6
7. Adaptive Parallel Distribution
Parallel Queries requiring Hash distribution
New adaptive parallel distribution method called Hybrid Hash
distribution technique
Optimizer decides distribution method between Hash and
Broadcast at run time based on rows buffered by statistics collector
No. of rows returned < 2*DOP
Left-input: Broadcast
Right-input: Round-Robin
No. of rows returned >= 2*DOP
Left-input: Hash
Right-input: Hash
Used for each execution of the statement.
OTN yathra 2015 Anju Garg 7
8. Adaptive Joins
• Initial join method : Hash or Nested Loops join
• Initial cardinality misestimates
• Join method can dynamically change between Nested Loop and
Hash join at run time based on rows buffered by statistics collector
• The final plan generated is stored for future use
• Information learnt is persisted as SQL plan directives (SPD)
• Subsequent executions use stored plan until cached
• Used during initial execution of the statement
OTN yathra 2015 Anju Garg 8
9. Automatic Re-optimization
OTN yathra 2015 Anju Garg
9
• CBO switches to a better plan during subsequent executions.
• When?
– Optimizer requires more information than base table statistics.
– Adaptive Plans cannot be employed as
default and final plans have the different starting points.
Initial join method : Sort Merge
Parallel query does not require Hash distribution
• How?
– Information learnt during initial execution persisted in SPD and employed
during subsequent executions.
– Augmented statistics used to improve subsequent executions.
– if (identical query and cursor is cached)
Use statistics feedback
else (Similar query or cursor has aged out)
if column group statistics gathered
Use column group statistics
else
Use dynamic statistics
10. SQL Plan Directives (SPD)
• A key component of Automatic Query optimization framework.
• Created as a result of significant cardinality misestimates during the execution
of a SQL .
• Assist the optimizer in generating a more optimal plan for future executions of
the statement
– Record missing group statistics. Subsequent DBMS_STATS calls result in
creation of column groups automatically.
– Instruct the optimizer to use column group statistics if they have been
gathered , else perform dynamic sampling.
• Defined for a query expression.
• Not tied to a specific SQL statement.
• Applicable to multiple SQL statements with similar predicates.
OTN yathra 2015 Anju Garg 10
18. Illustration - I: Adaptive Parallel Distribution
istributionSummary:
• In case of Parallel queries requiring hash distribution, new Hybrid Hash
distribution technique is employed.
• Distribution method of Hash or Broadcast is decided at run time based on rows
buffered by statistics collector.
• If No. of rows returned are < (2*DOP)
Left-input : Broadcast
Right-input : Round-Robin
• If No. of rows returned are >= (2*DOP)
Left-input : Hash
Right-input : Hash
Hybrid Hash Distribution technique is employed during every execution of the
parallel queries.
OTN yathra 2015 Anju Garg 18
20. Illustration - II: Cardinality Feedback in 11g
• What to expect?
• Cardinality feedback usage by a SQL
• Cardinality estimate aging out with cursor
OTN yathra 2015 Anju Garg 20
21. Illustration - II: Cardinality Feedback in 11g
• Basic Statistics gathered
• Complex predicates
• Optimizer estimates EMP table to return 5 rows (Actual = 2 rows)
• Parse time Plan Join Method : Hash Join.
DB11g>explain plan for
select /*+ monitor*/ department_name
from emp e, dept d
where e.dept_id = d.department_id
and e.salary > 1000
and e.name like 'J%‘
and d.department_id > 10;
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
Plan hash value: 3249786240
-----------------------------------------------------------------------------
| Id | Operation | Name |Rows|Bytes|Cost %CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 |155 |6 (17)|0:00:01 |
|* 1 | HASH JOIN | | 5 |155 |6 (17)|00:00:01|
|* 2 | TABLE ACCESS FULL |EMP | 5 | 75 |3 (0)|00:00:01|
| 3 | TABLE ACCESS BY INDEX ROWID|DEPT |26 |416 |2 (0)|00:00:01|
|* 4 | INDEX RANGE SCAN |DEPT_ID_IDX|26 | |1 (0)|00:00:01|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
2 - filter("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000)
4 - access("D"."DEPARTMENT_ID">10)
OTN yathra 2015 Anju Garg
21
22. Illustration - II: Cardinality Feedback in 11g
• First execution of query – misestimates 5 rows to be returned (Actual = 2 rows)
• Final Plan Join Method : Hash Join (same as parse time plan)
DB11g>select /*+ monitor*/ department_name
from emp e, dept d
where e.dept_id = d.department_id
and e.salary > 1000
and e.name like 'J%'
and d.department_id > 10;
select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 09daa1tu337ca, child number 1
-------------------------------------
select /*+ monitor*/ department_name from emp e, dept d where e.dept_id = d.department_id and e.salary > 1000
and e.name like 'J%' and d.department_id > 10
Plan hash value: 3249786240
-----------------------------------------------------------------------------
| Id| Operation | Name |Rows|Bytes|Cost(%CPU)|Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | |6 (100)| |
|* 1 | HASH JOIN | | 5 | 155 |6 (17)| 0:00:01|
|* 2 | TABLE ACCESS FULL |EMP | 5 | 75 |3 (0)|00:00:01|
| 3 | TABLE ACCESS BY INDEX ROWID|DEPT | 26 | 416 |2 (0)|00:00:01|
|* 4 | INDEX RANGE SCAN |DEPT_ID_IDX| 26 | |1 (0)|00:00:01|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
2 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000))
4 - access("D"."DEPARTMENT_ID">10)
OTN yathra 2015 Anju Garg 22
23. Illustration - II: Cardinality Feedback in 11g
• Second execution of the query employs cardinality feedback (cursor cached)
• No. of rows returned by EMP accurately estimated to be 2
• Join method changes to Nested Loops.
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 09daa1tu337ca, child number 2
-------------------------------------
select /*+ monitor*/ department_name from emp e, dept d where e.dept_id = d.department_id and e.salary >
1000 and e.name like 'J%' and d.department_id > 10
Plan hash value: 1970561632
-----------------------------------------------------------------------------
| Id | Operation |Name |Rows|Bytes|Cost(%CPU)|Time |
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | | |5 (100)| |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 2 | 62 |5 (0)| 00:00:01|
|* 3 | TABLE ACCESS FULL |EMP | 2 | 30 |3 (0)| 00:00:01|
|* 4 | INDEX RANGE SCAN |DEPT_ID_IDX| 1 | |0 (0)| |
| 5 | TABLE ACCESS BY INDEX ROWID|DEPT | 1 | 16 |1 (0)| 00:00:01|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000))
4 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID">10)
Note
-----
- cardinality feedback used for this statement
OTN yathra 2015 Anju Garg 23
24. Illustration - II: Cardinality Feedback in 11g
• Flush shared pool
• Third execution of the query : Optimizer misestimates cardinality again
(Execution statistics aged out with the cursor)
• Sub-optimal Join method (Hash join) chosen again
DB11g> alter system flush shared_pool;
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 09daa1tu337ca, child number 0
-------------------------------------
select /*+ monitor*/ department_name from emp e, dept d where e.dept_id = d.department_id and e.salary > 1000
and e.name like 'J%' and d.department_id > 10
Plan hash value: 3249786240
-----------------------------------------------------------------------------
|Id | Operation | Name |Rows|Bytes|Cost(%CPU)|Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | |6(100)| |
|* 1 | HASH JOIN | | 5 | 155|6 (17)| 00:00:01|
|* 2 | TABLE ACCESS FULL |EMP | 5 | 75|3 (0)| 00:00:01|
| 3 | TABLE ACCESS BY INDEX ROWID|DEPT | 26 | 416|2 (0)| 00:00:01|
|* 4 | INDEX RANGE SCAN |DEPT_ID_IDX| 26 | |1 (0)| 00:00:01|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
2 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000))
4 - access("D"."DEPARTMENT_ID">10)
OTN yathra 2015 Anju Garg 24
25. Illustration - II : Cardinality Feedback in 11g
OTN yathra 2015 Anju Garg 25
Summary:
• In case of significant cardinality misestimates, execution statistics are stored in
the cursor itself.
• Until cursor is cached, Cardinality feedback is used during subsequent
executions.
• After the cursor ages out, cardinality estimate is lost and optimizer again
misestimates cardinality.
27. Illustration - III : Adaptive Joins in 12c
OTN yathra 2015 Anju Garg
27
What to expect?
• Initial cardinality misestimate
• Run-time changes to execution plan during
first execution of query
• Cursor marked re-optimizable
• SQL plan directive created
28. Illustration - III: Adaptive Joins in 12c
• Parse time plan: Initial cardinality misestimate (5 rows)
– Default Plan Join Method : Hash Join (same as 11g)
– Note - this is an adaptive plan
DB12c>explain plan for
select /*+ monitor*/ department_name
from emp e, dept d
where e.dept_id = d.department_id
and e.salary > 1000
and e.name like 'J%'
and d.department_id > 10;
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
Plan hash value: 1074770502
-----------------------------------------------------------------------------
|Id |Operation |Name |Rows|Bytes|Cost(%CPU)| Time |
-----------------------------------------------------------------------------
| 0|SELECT STATEMENT | | 5|155 |5(0)| 00:00:01|
|* 1| HASH JOIN | | 5|155 |5(0)| 00:00:01 |
|* 2| TABLE ACCESS FULL |EMP | 5|75 |3(0)| 00:00:01 |
| 3| TABLE ACCESS BY INDEX ROWID BATCHED|DEPT | 26|416 |2(0)| 00:00:01 |
|* 4 INDEX RANGE SCAN |DEPT_ID_IDX| 26| |1(0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
2 - filter("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000)
4 - access("D"."DEPARTMENT_ID">10)
Note
-----
- this is an adaptive plan
OTN yathra 2015 Anju Garg 28
Initial cardinality
misestimate
29. Illustration - III: Adaptive Joins in 12c
OTN yathra 2015 Anju Garg 29
•First execution : Join method changes from hash to nested loops at run-time.
– A statistics collector inserted in the plan
– Note : " this is an adaptive plan (rows marked '-' are inactive)“
Note : Output continued on next slides
Run-time changes
to plan
30. Illustration - III : Adaptive Joins in 12c
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 09daa1tu337ca, child number 0
-------------------------------------
select /*+ monitor*/ department_name from emp e, dept d where e.dept_id = d.department_id and e.salary > 1000
and e.name like 'J%' and d.department_id > 10
Plan hash value: 1970561632
-----------------------------------------------------------------------------------------------
| Id | Operation | |Rows|Bytes|Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 5 (100)| |
|- * 1 | HASH JOIN | | 5 | 155| 5 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 5 | 155| 5 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | | | | |
|- 4 | STATISTICS COLLECTOR | | | | | |
| * 5 | TABLE ACCESS FULL |EMP | 5 | 75| 3 (0)| 00:00:01 |
| * 6 | INDEX RANGE SCAN |DEPT_ID_IDX | 26 | | 1 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID |DEPT | 1 | 16| 2 (0)| 00:00:01 |
|- 8 | TABLE ACCESS BY INDEX ROWID BATCHED|DEPT | 26 | 416| 2 (0)| 00:00:01 |
|- * 9 | INDEX RANGE SCAN |DEPT_ID_IDX | 26 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
5 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000))
6 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID">10)
9 - access("D"."DEPARTMENT_ID">10)
Note
-----
- this is an adaptive plan (rows marked '-' are inactive)
Continued ...
OTN yathra 2015 Anju Garg 30
Run-time changes
to plan
31. Illustration - III : Adaptive Joins in 12c
Continued from last slide ...
Reoptimized plan:
-----------------
This cursor is marked for automatic reoptimization. The plan that is
expected to be chosen on the next execution is displayed below.
Plan hash value: 1970561632
-----------------------------------------------------------------------------
|Id |Operation | Name |Rows|Bytes|Cost(%CPU)| Time|
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | 1| 31| 5(0)| 00:00:01 |
| 1 | NESTED LOOPS | | 1| 31| 5(0)| 00:00:01 |
| 2 | NESTED LOOPS | | 2| 31| 5(0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL |EMP | 2| 30| 3(0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN |DEPT_ID_IDX| 1| | 0(0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID|DEPT | 1| 16| 1(0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000)
4 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID">10)
OTN yathra 2015 Anju Garg 31
– The plan expected to be chosen on the next execution
uses Nested Loops join
Note : Cursor marked
for re-optimization
32. Illustration - III : Adaptive Joins in 12c
• IS_RESOLVED_ADAPTIVE_PLAN = Y
– Adaptive Plan
• IS_REOPTIMIZABLE=Y
– Cursor marked for automatic re-optimization – will be hard parsed next time
DB12c>select sql_id, child_number, sql_text,
is_resolved_adaptive_plan resolved_adaptive_plan,
IS_REOPTIMIZABLE reoptimizable
from v$sql
where sql_id = '09daa1tu337ca';
SQL_ID CHILD_NUMBER SQL_TEXT RESOLVED_ADAPTIVE_PLAN REOPTIMIZABLE
------------- ------------ ----------------------------- ---------------------- -------------
09daa1tu337ca 0 select /*+ monitor*/ Y Y
department_name from
emp e, dept d where e
.dept_id = d.department_id
and e.salary > 1000
and e.name like 'J%'
and d.department_id
> 10
OTN yathra 2015 Anju Garg 32
Cursor marked for
re-optimization
33. Illustration - III : Adaptive Joins in 12c
OTN yathra 2015 Anju Garg
33
• The information learnt via dynamic plans is persisted as a SQL directive.
• Cardinality misestimates on columns DEPT_ID, NAME and SALARY of EMP table .
• On subsequent executions dynamic sampling should be performed.
DB12c> exec dbms_spd.flush_sql_plan_directive
select o.object_name object, o.subobject_name col_name,
o.object_type, d.type, d.state, d.reason
from dba_sql_plan_directives d, dba_sql_plan_dir_objects o
where d.DIRECTIVE_ID=o.DIRECTIVE_ID
and o.owner in ('HR')
and o.object_name in ('EMP','DEPT')
order by object_type;
OBJECT COL_NAM OBJECT TYPE STATE REASON
------ ------- -------- ---------------- ------ ------------------------------------
EMP NAME COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
EMP DEPT_ID COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
EMP SALARY COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
EMP xx TABLE DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
SPD created
34. Illustration - III : Adaptive Joins in 12c
Summary:
• In case of initial cardinality misestimates, Adaptive Plans can change the
execution plan at run time during the first execution itself.
• The resulting cursor is marked for re-optimization and execution statistics are
stored in the cursor.
• Information learnt via Adaptive Plans is persisted as SQL Plan Directive.
OTN yathra 2015 Anju Garg 34
36. Illustration – IV: Automatic Re-optimization-I
OTN yathra 2015 Anju Garg 36
What to expect?
•During subsequent executions of query
Until cursor is cached, Statistics feedback is
used.
After cursor ages out, SPD is checked and
Dynamic sampling is performed.
SPD can be used for similar statements.
37. Illustration – IV: Automatic Re-optimization-I
• Second Execution
– Buffering of rows by collector disabled.
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 09daa1tu337ca, child number 1
-------------------------------------
select /*+ monitor*/ department_name from emp e, dept
d where e.dept_id = d.department_id and e.salary >
1000 and e.name like 'J%' and d.department_id > 10
Plan hash value: 1970561632
-----------------------------------------------------------------------------
|Id |Operation |Name |Rows |Bytes|Cost(%CPU)|Time |
-----------------------------------------------------------------------------
| 0|SELECT STATEMENT | | | | 5 (100)| |
| 1| NESTED LOOPS | | 1 | 31| 5 (0)|00:00:01|
| 2| NESTED LOOPS | | 2 | 31| 5 (0)|00:00:01|
|* 3| TABLE ACCESS FULL |EMP | 2 | 30| 3 (0)|00:00:01|
|* 4| INDEX RANGE SCAN |DEPT_ID_IDX| 1 | | 0 (0)| |
| 5 TABLE ACCESS BY INDEX ROWID|DEPT | 1 | 16| 1 (0)|00:00:01|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000))
4 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID">10)
Note
-----
- statistics feedback used for this statement
OTN yathra 2015 Anju Garg
37
Issue SQL second time
Cursor cached
Use statistics feedback
38. Illustration-IV: Automatic Re-optimization-I
• SQL Plan directive persists even after shared pool is flushed.
• Performs dynamic sampling with appropriate level (2) even
though basic statistics exist.
DB12c> alter system flush shared_pool;
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 09daa1tu337ca, child number 0
-------------------------------------
select /*+ monitor*/ department_name from emp e, dept d where e.dept_id = d.department_id and e.salary > 1000 and e.name
like 'J%' and d.department_id > 10
Plan hash value: 1970561632
----------------------------------------------------------------------------
|Id |Operation |Name |Rows|Bytes|Cost(%CPU)| Time|
|---------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | | | 5(100)| |
| 1 | NESTED LOOPS | | 2 | 62 | 5(0) |00:00:01|
| 2 | NESTED LOOPS | | 2 | 62 | 5(0) |00:00:01|
|* 3 | TABLE ACCESS FULL |EMP | 2 | 30 | 3(0) |00:00:01|
|* 4 | INDEX RANGE SCAN |DEPT_ID_IDX| 1 | | 0(0) | |
| 5 | TABLE ACCESS BY INDEX ROWID|DEPT | 1 | 16 | 1(0) |00:00:01|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">10 AND "E"."SALARY">1000))
4 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID">10)
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- this is an adaptive plan
- 1 Sql Plan Directive used for this statement
OTN yathra 2015 Anju Garg 38
Cursor flushed out
Subsequent execution
Check directive
Use dynamic Statistics
39. Illustration - IV: Automatic Re-optimization-I
• Hard parse results in an new cursor
• Cannot be optimized further (IS_REOPTIMIZABLE = N)
• Will be used for subsequent executions until cached.
DB12c>select sql_id, child_number, sql_text, IS_REOPTIMIZABLE reoptimizable
from v$sql
where sql_id = '09daa1tu337ca';
SQL_ID CHILD_NUMBER SQL_TEXT REOPTIMIZABLE
------------- ------------ ------------------------------ -------------
09daa1tu337ca 0 select /*+ monitor*/ Y
department_name from
emp e, dept d where e
.dept_id = d.department_id
and e.salary > 1000
and e.name like 'J%'
and d.department_id
> 10
09daa1tu337ca 1 select /*+ monitor*/ N
OTN yathra 2015 Anju Garg
39
40. Illustration-IV: Automatic Re-optimization-I
• CBO can use directives for statements having similar predicate.
DB12c>select /*+ monitor*/ name
from emp e, dept d
where e.dept_id = d.department_id
and e.salary > 1000
and e.name like 'J%'
and d.department_id > 11;
select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID as8qw9s1jdc77, child number 0
-------------------------------------
select /*+ monitor*/ name from emp e, dept d where e.dept_id = d.department_id and e.salary > 1000 and e.name
like 'J%' and d.department_id > 11
Plan hash value: 2629897806
-----------------------------------------------------------------------------
| Id | Operation | Name |Rows |Bytes|Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
| 1 | NESTED LOOPS | | 2 | 38 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| EMP | 2 | 30 | 3 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | DEPT_ID_IDX | 1 | 4 | 0 (0)| |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("E"."NAME" LIKE 'J%' AND "E"."DEPT_ID">11 AND
"E"."SALARY">1000))
3 - access("E"."DEPT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID">11)
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- 1 Sql Plan Directive used for this statement
OTN yathra 2015 Anju Garg 40
41. Illustration-IV: Automatic Re-optimization-I
Summary:
• Until the cursor is cached, subsequent executions of identical query employ
statistics feedback.
• After the cursor ages out, subsequent hard parse uses SPD resulting in use
of dynamic statistics.
• Directives can be used for queries using similar predicate also.
OTN yathra 2015 Anju Garg 41
43. Illustration–V : Automatic Re-optimization-II
OTN yathra 2015 Anju Garg 43
What to expect?
• First execution of query is sub-optimal as Plan is
not adaptive.
• Cursor is marked re-optimizable and SPD created
• Second execution employs statistics feedback as
cursor is cached.
• Gathering statistics causes automatic creation of
column group
•After shared pool is flushed, subsequent
executions check SPD and
• Use column group statistics , if gathered.
• Else perform dynamic sampling
• SPD can be used for similar statements.
44. Illustration–V: Automatic Re-optimization-II
OTN yathra 2015 Anju Garg 44
• Table HR.BIRTHDAYS
• Correlation between columns
– DOW (Numeric day of week) and
– DOW_DESC (Literal day of week)
• Basic Statistics gathered
DB12c> select distinct dow, dow_desc from hr.birthdays order by dow;
DOW DOW
---------- ---
1 SUN
2 MON
3 TUE
4 WED
5 THU
6 FRI
7 SAT
7 rows selected.
45. Illustration–V: Automatic Re-optimization-II
• First execution
– Query columns DOW and DOW_DESC together
– Missing column group
– Dynamic sampling not done (Default sampling level = 2 and basic statistics exist)
– Estimated rows (204) << Actual rows (1428)
DB12c>select /*+ gather_plan_statistics */ count(*)
from hr.birthdays
where dow = 1 and dow_desc = 'SUN';
select * from table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST +REPORT'));
PLAN_TABLE_OUTPUT
--------------------------------------------------
SQL_ID 16fzuw8m34vas, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(*) from hr.birthdays where
dow = 1 and dow_desc = 'SUN'
Plan hash value: 1914637537
-----------------------------------------------------------------------------
|Id |Operation |Name |Starts|E-Rows|A-Rows| A-Time |Buffers|
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | 1 | | 1|00:00:00.01| 61|
| 1 | SORT AGGREGATE | | 1 | 1 | 1|00:00:00.01| 61|
|* 2 | TABLE ACCESS FULL|BIRTHDAYS| 1 | 204 | 1428|00:00:00.01| 61|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DOW"=1 AND "DOW_DESC"='SUN'))
Continued…
OTN yathra 2015 Anju Garg 45
Issue SQL first time
Cardinality misestimate
46. Illustration–V: Automatic Re-optimization-II
• As optimizer's estimates are way off the mark
– Monitoring is enabled for statistics feedback
– Cursor is marked for re-optimization
– The plan that is expected to be chosen on the next execution is displayed.
... Continued from last slide
Reoptimized plan:
-----------------
This cursor is marked for automatic reoptimization. The plan that is
expected to be chosen on the next execution is displayed below.
Plan hash value: 1914637537
------------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |
| 1 | SORT AGGREGATE | | 1 |
|* 2 | TABLE ACCESS FULL| BIRTHDAYS | 1428 |
------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("DOW"=1 AND "DOW_DESC"='SUN')
OTN yathra 2015 Anju Garg 46
Note: Cursor marked
for re-optimization
47. Illustration–V: Automatic Re-optimization-II
• Cursor is marked as re-optimizable (IS_REOPTIMIZABLE = Y).
– Will be hard parsed next time
DB12c> SELECT SQL_ID, CHILD_NUMBER, IS_REOPTIMIZABLE, SQL_TEXT
FROM V$SQL
WHERE SQL_ID = '16fzuw8m34vas';
SQL_ID CHILD_NUMBER IS_REOPTIMIZABLE SQL_TEXT
------------- ------------ ----------------- --------------------------------
16fzuw8m34vas 0 Y select /*+
gather_plan_statistics */
count(*) from hr.birthdays where
dow = 1 and dow_desc = 'SUN'
OTN yathra 2015 Anju Garg
47
Cursor marked for
re-optimization
48. Illustration–V: Automatic Re-optimization-II
• SQL Plan Directive generated
– REASON = SINGLE TABLE CARDINALITY MISESTIMATE
– STATE = USABLE (column group does not exist yet )
– TYPE = DYNAMIC_SAMPLING
DB12c>exec DBMS_SPD.FLUSH_SQL_PLAN_DIRECTIVE;
SELECT TO_CHAR(d.DIRECTIVE_ID) dir_id, o.OWNER, o.OBJECT_NAME OBJECT,
o.SUBOBJECT_NAME col_name, o.OBJECT_TYPE, d.TYPE, d.STATE,
d.REASON
FROM DBA_SQL_PLAN_DIRECTIVES d, DBA_SQL_PLAN_DIR_OBJECTS o
WHERE d.DIRECTIVE_ID=o.DIRECTIVE_ID
AND o.OBJECT_NAME = 'BIRTHDAYS'
ORDER BY 1,2,3,4,5;
DIR_ID OWNER OBJECT COL_NAME OBJECT_TYP TYPE STATE REASON
------------------------- ------- --------- ---------- ---------- ---------- ---------- --------------------
15511226280058347046 HR BIRTHDAYS DOW COLUMN DYNAMIC_SA USABLE SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
15511226280058347046 HR BIRTHDAYS DOW_DESC COLUMN DYNAMIC_SA USABLE SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
15511226280058347046 HR BIRTHDAYS xx TABLE DYNAMIC_SA USABLE SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
OTN yathra 2015 Anju Garg 48
SPD created
49. Illustration–V: Automatic Re-optimization-II
• Second execution
– Uses statistics feedback from last execution
PLAN_TABLE_OUTPUT
--------------------------------------------------
SQL_ID 16fzuw8m34vas, child number 1
-------------------------------------
select /*+ gather_plan_statistics */ count(*) from hr.birthdays where
dow = 1 and dow_desc = 'SUN'
Plan hash value: 1914637537
-----------------------------------------------------------------------------
|Id |Operation |Name |Starts|E-Rows|A-Rows| A-Time |Buffers|
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | 1 | | 1 |00:00:00.01 61 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01| 61 |
|* 2 | TABLE ACCESS FULL|BIRTHDAYS| 1 | 1428 | 1428 |00:00:00.01| 61 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DOW"=1 AND "DOW_DESC"='SUN'))
Note
-----
- statistics feedback used for this statement
OTN yathra 2015 Anju Garg 49
Issue SQL second time
Cursor cached
Use statistics feedback
50. Illustration–V: Automatic Re-optimization-II
• A new cursor (CHILD_NUMBER = 1) has been created.
• New cursor cannot be optimized further (IS_REOPTIMIZABLE = N) .
• Subsequent executions will use the new cursor, if cached.
DB12c>SELECT SQL_ID, CHILD_NUMBER, IS_REOPTIMIZABLE, SQL_TEXT
FROM V$SQL
WHERE SQL_ID = '16fzuw8m34vas';
SQL_ID CHILD_NUMBER IS_REOPTIMIZABLE SQL_TEXT
------------- ------------ -------------------- -----------------------
16fzuw8m34vas 0 Y select /*+ gather_plan_statistics */ count(*) from hr.birthdays
where dow = 1
and dow_desc = 'SUN'
16fzuw8m34vas 1 N select /*+ gather_plan_statistics */ count(*) from hr.birthdays
where dow = 1
and dow_desc = 'SUN'
OTN yathra 2015 Anju Garg
50
51. Illustration–V: Automatic Re-optimization-II
Execution of a similar SQL with same query expression
• Hard parsing takes place
• The directive is applied (Directives are not tied to any SQL )
• Dynamic Statistics used: Dynamic sampling (level 2) is performed ( STATUS = USABLE).
Accurate cardinality estimate
DB12c>select /*+ gather_plan_statistics */ count(*)
from hr.birthdays
where dow = 2 and dow_desc = 'MON';
select * from table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 2jjsaw12bw01d, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(*) from hr.birthdays where
dow = 2 and dow_desc = 'MON'
Plan hash value: 1914637537
-----------------------------------------------------------------------------
|Id |Operation |Name |Starts|E-Rows|A-Rows| A-Time |Buffers|
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | 1 | | 1 |00:00:00.01| 61 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01| 61 |
|* 2 | TABLE ACCESS FULL|BIRTHDAYS| 1 | 1428 | 1428 |00:00:00.01| 61 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DOW"=2 AND "DOW_DESC"='MON'))
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- 1 Sql Plan Directive used for this statement
OTN yathra 2015 Anju Garg 51
52. Illustration–V: Automatic Re-optimization-II
• Statistics gathered for HR.BIRTHDAYS
– Directives on the table are checked
– Column group created automatically for the columns DOW and DOW_DESC
DB12c>SELECT TABLE_NAME, EXTENSION_NAME, EXTENSION
FROM DBA_STAT_EXTENSIONS
WHERE OWNER='HR'
AND TABLE_NAME='BIRTHDAYS';
no rows selected
DB12c> exec dbms_stats.gather_table_stats('HR', 'BIRTHDAYS');
SELECT TABLE_NAME, EXTENSION_NAME, EXTENSION
FROM DBA_STAT_EXTENSIONS
WHERE OWNER='HR'
AND TABLE_NAME='BIRTHDAYS';
TABLE_NAME EXTENSION_NAME EXTENSION
--------------- ------------------------------ ------------------------------
BIRTHDAYS SYS_STSHCU09AIP06LHNSCFSKPJQ1P ("DOW","DOW_DESC")
OTN yathra 2015 Anju Garg
52
53. Illustration–V: Automatic Re-optimization-II
• The directive still has a state of USABLE as earlier
– The statement has not been recompiled after creation of extended statistics
DB12c>EXEC DBMS_SPD.FLUSH_SQL_PLAN_DIRECTIVE;
SELECT TO_CHAR(d.DIRECTIVE_ID) dir_id, o.OWNER, o.OBJECT_NAME,
o.SUBOBJECT_NAME col_name, o.OBJECT_TYPE, d.TYPE, d.STATE, d.REASON
FROM DBA_SQL_PLAN_DIRECTIVES d, DBA_SQL_PLAN_DIR_OBJECTS o
WHERE d.DIRECTIVE_ID=o.DIRECTIVE_ID
AND o.OBJECT_NAME = 'BIRTHDAYS'
ORDER BY 1,2,3,4,5;
DIR_ID OWNER OBJECT_NAME COL_NAME OBJECT_TYP TYPE STATE REASON
------------------------- ------ ------------ -------- ---------- ---------- ---------- --------------------
15511226280058347046 HR BIRTHDAYS DOW COLUMN DYNAMIC_SA USABLE SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
15511226280058347046 HR BIRTHDAYS DOW_DESC COLUMN DYNAMIC_SA USABLE SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
15511226280058347046 HR BIRTHDAYS xx TABLE DYNAMIC_SA USABLE SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
OTN yathra 2015 Anju Garg
53
54. Illustration–V: Automatic Re-optimization-II
• Force reparsing of the cursor .
– Optimizer checks the directive (SPD STATE =USABLE)
– Performs dynamic sampling
DB12c>select /*+ gather_plan_statistics REPARSE*/ count(*)
from hr.birthdays
where dow = 1 and dow_desc = 'SUN';
select * from table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 6r41c03nunmdp, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(*) from hr.birthdays
where dow = 1 and dow_desc = 'SUN'
Plan hash value: 1914637537
------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 61 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 61 |
|* 2 | TABLE ACCESS FULL| BIRTHDAYS | 1 | 1428 | 1428 |00:00:00.01 | 61 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DOW"=1 AND "DOW_DESC"='SUN'))
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- 1 Sql Plan Directive used for this statement
OTN yathra 2015 Anju Garg 54
Subsequent execution
Force reparse
Check directive (USABLE)
Use dynamic Statistics
55. Illustration–V: Automatic Re-optimization-II
• Reparsing of the statement causes STATE of the directive to change to SUPERSEDED
– An extension has been created for the corresponding column group
– Subsequent executions should use extended statistics instead of dynamic sampling.
DB12c>EXEC DBMS_SPD.FLUSH_SQL_PLAN_DIRECTIVE;
SELECT TO_CHAR(d.DIRECTIVE_ID) dir_id, o.OWNER, o.OBJECT_NAME,
o.SUBOBJECT_NAME col_name, o.OBJECT_TYPE, d.TYPE, d.STATE,
d.REASON
FROM DBA_SQL_PLAN_DIRECTIVES d, DBA_SQL_PLAN_DIR_OBJECTS o
WHERE d.DIRECTIVE_ID=o.DIRECTIVE_ID
AND o.OBJECT_NAME = 'BIRTHDAYS'
ORDER BY 1,2,3,4,5;
DIR_ID OWNER OBJECT_NAME COL_NAME OBJECT_TYP TYPE STATE REASON
------------------------- ------- --------------- ---------- ---------- ---------- ---------- --------------------
12589029473066064605 HR BIRTHDAYS DOW COLUMN DYNAMIC_SA SUPERSEDED SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
12589029473066064605 HR BIRTHDAYS DOW_DESC COLUMN DYNAMIC_SA SUPERSEDED SINGLE TABLE CARDINA
MPLING LITY MISESTIMATE
12589029473066064605 HR BIRTHDAYS TABLE DYNAMIC_SA SUPERSEDED SINGLE TABLE CARDINA
OTN yathra 2015 Anju Garg
55
56. Illustration–V: Automatic Re-optimization-II
• Force reparse to use SUPERSEDED STATE of the directive
– Accurate estimate
• Extended statistics used
• No dynamic sampling (absence of a Note )
DB12c>select /*+ gather_plan_statistics */ /* force reparse */ count(*)
from hr.birthdays
where dow = 1 and dow_desc = 'SUN';
select * from table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 1yptyv4kdfk70, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ /* force reparse */ count(*) from
hr.birthdays where dow = 1 and dow_desc = 'SUN'
Plan hash value: 1914637537
-----------------------------------------------------------------------------
|Id |Operation |Name |Starts|E-Rows|A-Rows| A-Time |Buffers|
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | 1 | | 1 |00:00:00.01| 61|
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01| 61|
|* 2 | TABLE ACCESS FULL|BIRTHDAYS| 1 | 1428 | 1428 |00:00:00.01| 61|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DOW"=1 AND "DOW_DESC"='SUN'))
OTN yathra 2015 Anju Garg
56
Subsequent execution
Force reparse
Check directive (SUPERSEDED)
Use extended Statistics
57. Illustration–V: Automatic Re-optimization-II
• Issue a similar SQL selecting different column and with different values in predicate
– Checks existence of SPD
– Uses extended statistics (STATE = SUPERSEDED)
– Accurate estimate
DB12c> select /*+ gather_plan_statistics */ count(MM)
from hr.birthdays
where dow = 2 and dow_desc = 'MON';
select * from table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID 52u50yd55ad4x, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(MM) from hr.birthdays where
dow = 2 and dow_desc = 'MON'
Plan hash value: 1914637537
-----------------------------------------------------------------------------
|Id |Operation |Name |Starts|E-Rows|A-Rows| A-Time | Buffers|
-----------------------------------------------------------------------------
| 0 |SELECT STATEMENT | | 1 | | 1 |00:00:00.01| 61|
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01| 61|
|* 2 | TABLE ACCESS FULL|BIRTHDAYS| 1 | 1428 | 1428 |00:00:00.01| 61|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DOW"=2 AND "DOW_DESC"='MON'))
OTN yathra 2015 Anju Garg
57
58. Illustration–V: Automatic Re-optimization-II
Summary:
• In case of initial cardinality misestimates, if adaptive Plan cannot be employed,
SQL is executed with parse time sub-optimal plan.
• The resulting cursor is marked for re-optimization and execution statistics are
stored in the cursor.
• Information learnt via first execution is persisted as SQL Plan Directive which
records missing group statistics. Subsequent DBMS_STATS calls result in
creation of column groups automatically.
• Until the cursor is cached, subsequent executions of identical query employ
statistics feedback.
• After the cursor ages out, during subsequent executions, optimizer uses column
group statistics, if they have been gathered else performs dynamic sampling.
• Directives can be used for queries using similar predicate also.
OTN yathra 2015 Anju Garg 58
59. Conclusion
• In 12c, optimizer has evolved further as a result of a new adaptive approach to
query optimizations.
• Several enhancements to the statistical information available to optimizer.
• In all cases of significant cardinality misestimates, SQL Plan Directives are created
which record missing statistics and guide the optimizer during subsequent
executions of the statements that are identical or nearly identical.
• Adaptive Plans cause optimizer to make run-time adjustments to execution plans
during first execution.
• Automatic Re-optimization optimizes subsequent executions using information
gathered during earlier execution. Statistics Feedback is employed until reparsing
of the statement triggers application of SPD.
• In view of these enhancements, the optimizer should be able to select an optimal
execution plan every time.
OTN yathra 2015 Anju Garg 59