SlideShare a Scribd company logo
www.sagecomputing.com.au
penny@sagecomputing.com.au
the Cost Based Optimiser in
11g Rel 2
Penny Cookson
SAGE Computing Services
SAGE Computing Services
Customised Oracle Training Workshops and Consulting
SAGE Computing Services
Customised Oracle Training Workshops and Consulting
Penny Cookson
Managing Director and Principal Consultant
Working with Oracle products since 1987
Oracle Magazine Educator of the Year 2004
www.sagecomputing.com.au
penny@sagecomputing.com.au
Agenda
Extended Statistics
Kernel trace granularity - oradebug
Cardinality Feedback
Adaptive Cursors
New behaviours
Hints in 11g
Getting rid of your hints
Assessing plan changes on upgrade
Results cache
S
Gathering Statistics
Multi Column Statistics
Gather statistics on combinations of columns
Improves plans for complex dependency patterns
(and this is persistent)
SELECT count(b.comments)
FROM train.events_large e, train.bookings_large b
WHERE e.org_id = 2264
AND e.event_no = b.event_no
AND e.comments = 'TEST'
Multi Column Data Patterns
SELECT count(*)
FROM train.events_large e
SELECT count(*)
FROM train.events_large e
WHERE e.org_id = 2264
SELECT count(e.comments)
FROM train.events_large e
WHERE e.comments = 'TEST'
SELECT count(e.comments)
FROM train.events_large e
WHERE e.comments = 'TEST‘
AND e.org_id = 2264
With Individual Statistics
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 5.00 22.52 35341 36337 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 5.00 22.52 35341 36337 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 82
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=36337 pr=35341 pw=35341 time=0 us)
175 HASH JOIN (cr=36337 pr=35341 pw=35341 time=13 us cost=9966 size=33365083 card=1076293)
4 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=3 us cost=274 size=319770 card=18810)
5767168 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=225583 us cost=9665
size=80740352 card=5767168)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
direct path read 314 0.38 15.88
resmgr:cpu quantum 11 0.14 0.27
SQL*Net message from client 2 0.04 0.04
********************************************************************************
Auto Created Column Statistics
BEGIN
dbms_stats.gather_table_stats(ownname=>'TRAI1N',
tabname=>'EVENTS_LARGE', cascade=>TRUE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
no_invalidate=>FALSE);
END;
SELECT column_name, histogram, num_buckets
FROM user_tab_col_statistics
WHERE table_name = 'EVENTS_LARGE'
Auto Created Column Statistics
SELECT extension_name, extension
FROM user_stat_extensions
WHERE table_name='EVENTS_LARGE‘
So same access path used
********************************************************************************
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=36337 pr=35341 pw=35341 time=0 us)
175 HASH JOIN (cr=36337 pr=35341 pw=35341 time=13 us cost=9966 size=33365083 card=1076293)
4 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=3 us cost=274 size=319770 card=18810)
5767168 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=225583 us cost=9665
size=80740352 card=5767168)
Manually Create Multi Column Statistics
BEGIN
dbms_stats.gather_table_stats(ownname=>'TRAIN',
tabname=>'EVENTS_LARGE', cascade=>TRUE,
method_opt => 'FOR COLUMNS (org_id, comments) SIZE
SKEWONLY', no_invalidate=>FALSE);
END;
OR
dbms_stats.create_extended_stats('TRAIN1','EVENTS_LARGE','(OR
G_ID,COMMENTS)'); --(Then gather stats)
SELECT extension_name, extension
FROM user_stat_extensions
WHERE table_name='EVENTS_LARGE'
Manually Create Multi Column Statistics
SELECT column_name, histogram, num_buckets
FROM user_tab_col_statistics
WHERE table_name = 'EVENTS_LARGE'
Multi Column Statistics
********************************************************************************
SELECT count(b.comments)
FROM train.events_large e, train.bookings_large b
WHERE e.org_id = 2264
AND e.event_no = b.event_no
AND e.comments = 'TEST'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.01 0.01 0 1175 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.01 0.01 0 1175 0 1
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=1175 pr=0 pw=0 time=0 us)
175 NESTED LOOPS (cr=1175 pr=0 pw=0 time=71 us)
175 NESTED LOOPS (cr=1001 pr=0 pw=0 time=39 us cost=1129 size=26815 card=865)
4 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=4 us cost=274 size=255 card=15)
175 INDEX RANGE SCAN BK_EVT2 (cr=10 pr=0 pw=0 time=10 us cost=2 size=0 card=57)(object id 69868)
175 TABLE ACCESS BY INDEX ROWID BOOKINGS_LARGE (cr=174 pr=0 pw=0 time=0 us cost=57 size=798 card=57)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.02 0.02
********************************************************************************
Multi Column Statistics
********************************************************************************
SELECT count(b.comments)
FROM train.organisations o, train.events_large e, train.bookings_large b,
train.resources r
WHERE o.org_id = e.org_id
AND e.event_no = b.event_no
AND b.resource_code = r.code
AND o.name = 'Australian Medical Systems'
AND r.description = 'Buffet Lunch'
AND e.comments = 'TEST'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 4.64 21.66 35341 36351 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 4.64 21.66 35341 36351 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 82
Multi Column Statistics
********************************************************************************
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=36351 pr=35341 pw=35341 time=0 us)
25 HASH JOIN (cr=36351 pr=35341 pw=35341 time=1966789 us cost=9972 size=6555490
card=79945)
4 HASH JOIN (cr=1005 pr=0 pw=0 time=8 us cost=281 size=792225 card=12575)
1 MERGE JOIN CARTESIAN (cr=14 pr=0 pw=0 time=0 us cost=6 size=46 card=1)
1 TABLE ACCESS FULL ORGANISATIONS (cr=7 pr=0 pw=0 time=0 us cost=3 size=26
card=1)
1 BUFFER SORT (cr=7 pr=0 pw=0 time=0 us cost=3 size=20 card=1)
1 TABLE ACCESS FULL RESOURCES (cr=7 pr=0 pw=0 time=0 us cost=3 size=20
card=1)
75243 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=1020 us cost=274
size=1282616 card=75448)
5767168 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=350849 us
cost=9665 size=109576192 card=5767168)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
direct path read 314 0.35 15.49
resmgr:cpu quantum 2 0.12 0.12
SQL*Net message from client 2 0.04 0.05
********************************************************************************
Multi Column Statistics - Summary
Manually create column groups and statistics on them
Complex joins may still need SQL Profiles
Use for dependent column such as Country, State
Use DBMS_STATS.SEED_COL_USAGE to gather column
usage stats
Use DBMS_STATS.REPORT_COL_USAGE to report on col
usage stats
Gathering Statistics - Preferences
Setting Statistics Gathering Defaults
Obsolete:
GET_PARAM
SET_PARAM Procedure
Use:
GET_PREFS Function
SET_TABLE_PREFS (set for individual tables)
SET_GLOBAL_PREFS – for new objects
Table Prefs
PROCEDURE SET_TABLE_PREFS
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
OWNNAME VARCHAR2 IN
TABNAME VARCHAR2 IN
PNAME VARCHAR2 IN
PVALUE VARCHAR2 IN
PNAME
CASCADE
DEGREE
ESTIMATE_PERCENT
METHOD_OPT
NO_INVALIDATE
GRANULARITY
PUBLISH
INCREMENTAL (only scan partitions that have been changed)
STALE_PERCENT
Setting Statistics Gathering Defaults
Setting Statistics Gathering Defaults
Setting Statistics Gathering Defaults
Gathering and Publishing
Set preferences to PUBLISH = ‘FALSE’
Gather Statistics
user_tab_pending_stats
user_ind_pending_stats
user_col_pending_stats
Run test case
Alter session set
optimizer_pending_statistics
= TRUE
Run test case Worse
Better
dbms_stats.
delete_pending_stats
dbms_stats.
publish_pending_stats
user_tab_statistics
user_ind_statistics
user_tab_col_statistics
Gathering and Publishing
SELECT obj#, TO_CHAR(savtime,'dd/mm/yyyy') save_time,
rowcnt, blkcnt, avgrln, samplesize, analyzetime
FROM wri$_optstat_tab_history
ORDER BY savtime desc
Gathering and Publishing
Never publish any statistics until you
are happy they work better
Trace Granularity
Oracle 11g:
Improved Oracle diagnostic event infrastructure
ORADEBUG DOC
Tracing SQL Executions
ALTER SESSION SET EVENTS
'sql_trace[SQL: 324dr9k932njj]
plan_stat=all_executions,wait=true,bind=true';
SELECT count(b.comments)
FROM events_large e, bookings_large b
WHERE e.org_id = 2264
AND e.event_no = b.event_no
AND e.comments = 'TEST'
Execute this twice and format the trace file
ora11_ora_5852_324dr9k932njj.rtf.
Cardinality Feedback
We have been able to find information about this with
dbms_xplan since 10g:
Real cardinality v expected cardinality?
Cardinality Feedback
SELECT /*+ GATHER_PLAN_STATISTICS */
count(b.comments)
FROM events_large e, bookings_large b
WHERE e.org_id = 2264
AND e.event_no = b.event_no
AND e.comments = 'TEST'
SELECT
DBMS_XPLAN.DISPLAY_CURSOR
(FORMAT=>'ALLSTATS LAST')
FROM dual;
Cardinality Feedback
SYS.DBMS_XPLAN_TYPE('SQL_ID 2yxvxc5r9z6tv, child number 0')
SYS.DBMS_XPLAN_TYPE('-------------------------------------')
SYS.DBMS_XPLAN_TYPE('SELECT /*+ GATHER_PLAN_STATISTICS */ count(b.comments) FROM ')
SYS.DBMS_XPLAN_TYPE('events_large e, bookings_large b WHERE e.org_id = 2264 AND e.event_no ')
SYS.DBMS_XPLAN_TYPE('= b.event_no AND e.comments = 'TEST'')
SYS.DBMS_XPLAN_TYPE(' ')
SYS.DBMS_XPLAN_TYPE('Plan hash value: 3269294976')
SYS.DBMS_XPLAN_TYPE(' ')
SYS.DBMS_XPLAN_TYPE('----------------------------------------------------------------------------------------------------------
--------------------------')
SYS.DBMS_XPLAN_TYPE('| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
OMem | 1Mem | Used-Mem |')
SYS.DBMS_XPLAN_TYPE('----------------------------------------------------------------------------------------------------------
--------------------------')
SYS.DBMS_XPLAN_TYPE('| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:02.23 | 36451 | 741 |
| | |')
SYS.DBMS_XPLAN_TYPE('| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:02.23 | 36451 | 741 |
| | |')
SYS.DBMS_XPLAN_TYPE('|* 2 | HASH JOIN | | 1 | 398K| 232 |00:00:13.89 | 36451 | 741 |
1452K| 1452K| 630K (0)|')
SYS.DBMS_XPLAN_TYPE('|* 3 | TABLE ACCESS FULL| EVENTS_LARGE | 1 | 6967 | 4 |00:00:00.01 | 992 | 0 |
| | |')
SYS.DBMS_XPLAN_TYPE('| 4 | TABLE ACCESS FULL| BOOKINGS_LARGE | 1 | 5767K| 5767K|00:00:01.64 | 35459 | 741 |
| | |')
SYS.DBMS_XPLAN_TYPE('----------------------------------------------------------------------------------------------------------
--------------------------')
SYS.DBMS_XPLAN_TYPE(' ')
SYS.DBMS_XPLAN_TYPE('Predicate Information (identified by operation id):')
SYS.DBMS_XPLAN_TYPE('---------------------------------------------------')
SYS.DBMS_XPLAN_TYPE(' ')
SYS.DBMS_XPLAN_TYPE(' 2 - access("E"."EVENT_NO"="B"."EVENT_NO")')
SYS.DBMS_XPLAN_TYPE(' 3 - filter(("E"."ORG_ID"=2264 AND "E"."COMMENTS"='TEST'))')
SYS.DBMS_XPLAN_TYPE(' ')
Cardinality Feedback
Cursor Cache
Execute the SQL
Cursor Cache
Parse the SQL
Transform
Estimate cost
Generate
execution plan
Cardinality Feedback
If it has to do this it has got it wrong once
and
Its not persistent so it will keep getting it wrong once
Cardinality Feedback
Create your statistics so Oracle does not need to do this
dbms_stats.create_extended_stats
('TRAIN1','EVENTS_LARGE','(ORG_ID,COMMENTS)');
SELECT count(b.comments)
FROM events_large e, bookings_large b
WHERE e.org_id = 2264
AND e.event_no = b.event_no
AND e.comments = 'TEST'
Cardinality Feedback
Set optimizer_dynamic_sampling so Oracle does not need
to do this
SELECT /*+ dynamic_sampling (4) */ count(b.comments)
FROM events_large e, bookings_large b
WHERE e.org_id = 2264
AND e.event_no = b.event_no
AND e.comments = 'TEST'
Cardinality Feedback
No use across multiple tables
SELECT count(b.comments)
FROM organisations o, events_large e,
bookings_large b
WHERE o.org_id = e.org_id
AND e.event_no = b.event_no
AND o.name = 'Australian Medical Systems'
AND e.comments = 'TEST'
Cardinality Feedback
Use optimizer_scaling to correct multi table estimates
SELECT /*+ opt_estimate(JOIN,("E","O"),
SCALE_ROWS= 0.000001) */ count(b.comments)
FROM organisations o, events_large e,
bookings_large b
WHERE o.org_id = e.org_id
AND e.event_no = b.event_no
AND o.name = 'Australian Medical Systems'
AND e.comments = 'TEST'
Cardinality Feedback
Was it used?
Cardinality Feedback
Oracle asking Did I get it right?
Need stable data patterns
Can use where poor stats and no dynamic sampling
Designed to correct mistakes
Not for bind variables
Only once per plan
Not persistent
A Characteristic Problem
I haven’t changed anything
Its really slow this morning
I did the same thing yesterday and it was fine
Actually its OK now
No its not
Thank you so much you’ve fixed it (I haven’t done anything)
Bind Peeking + Adaptive Cursors
SELECT resource_code, count(*)
FROM bookings_large
GROUP BY resource_code;
Majority value
Minority value
Bind Peeking
Look at the value of the bind variable when the statement is
parsed
Plan is based on that value
BEGIN :v3 := ‘PC1'; END;
SELECT COUNT(quantity)
FROM bookings_large
WHERE resource_code = :v3;
BEGIN :v3 := ‘BRLG'; END;
SELECT COUNT(quantity)
FROM bookings_large
WHERE resource_code = :v3;
SAME PLAN
STILL INDEX
for 34% of rows
INDEX
for <1% of rows
Bind Peeking + Adaptive Cursors
SELECT COUNT(l.quantity) FROM train.bookings_large l
WHERE resource_code = :v1
SELECT sql_id FROM v$sqlarea
WHERE sql_text = 'SELECT COUNT(l.quantity)
FROM train.bookings_large l WHERE resource_code = :v1'
Bind Peeking + Adaptive Cursors
BEGIN :v1 := 'PC1'; END;
SELECT COUNT(l.quantity) FROM train.bookings_large l
WHERE resource_code = :v1
SELECT sql_id, child_number, is_bind_sensitive, is_bind_aware
FROM v$sql
WHERE sql_id ='95jktg3mza0qm';
IS_BIND_SENSITIVE - may need to change the plan
- set on first execution of the
statement
IS_BIND_AWARE - do need to change the plan
Bind Peeking + Adaptive Cursors
SELECT child_number, bind_set_hash_value, peeked, executions,
rows_processed, buffer_gets
FROM v$sql_cs_statistics
WHERE sql_id ='95jktg3mza0qm'
Bind Peeking + Adaptive Cursors
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.01 0 0 0 0
Fetch 2 0.12 0.43 119 6635 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.14 0.44 119 6635 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 82
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=6635 pr=119 pw=119 time=0 us)
48510 TABLE ACCESS BY INDEX ROWID BOOKINGS_LARGE (cr=6635 pr=119 pw=119 time=2870 us
cost=1977 size=316008 card=39501)
48510 INDEX RANGE SCAN BK_RES2 (cr=104 pr=0 pw=0 time=527 us cost=90 size=0
card=39501)(object id 69870)
********************************************************************************
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.00 0.00
********************************************************************************
Bind Peeking + Adaptive Cursors
BEGIN :v1 := ‘BRLG'; END;
SELECT COUNT(l.quantity) FROM train.bookings_large l
WHERE resource_code = :v1
SELECT sql_id, child_number, is_bind_sensitive, is_bind_aware
FROM v$sql
WHERE sql_id ='95jktg3mza0qm';
Bind Peeking + Adaptive Cursors
SELECT child_number, bind_set_hash_value, peeked, executions,
rows_processed, buffer_gets
FROM v$sql_cs_statistics
WHERE sql_id ='95jktg3mza0qm'
Bind Peeking + Adaptive Cursors
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 6.29 78.82 34335 39594 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 6.29 78.82 34335 39594 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 82
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=39594 pr=34335 pw=34335 time=0 us)
1991051 TABLE ACCESS BY INDEX ROWID BOOKINGS_LARGE (cr=39594 pr=34335 pw=34335 time=626800
us cost=1977 size=316008 card=39501)
1991051 INDEX RANGE SCAN BK_RES2 (cr=4437 pr=4436 pw=4436 time=61616 us cost=90 size=0
card=39501)(object id 69870)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
db file sequential read 34335 0.29 72.08
resmgr:cpu quantum 30 0.10 1.29
SQL*Net message from client 2 0.00 0.00
Bind Peeking + Adaptive Cursors
BEGIN :v1 := ‘BRLG'; END;
SELECT COUNT(l.quantity) FROM train.bookings_large l
WHERE resource_code = :v1
SELECT sql_id, child_number, is_bind_sensitive, is_bind_aware
FROM v$sql
WHERE sql_id ='95jktg3mza0qm';
Bind Peeking + Adaptive Cursors
SELECT child_number, bind_set_hash_value, peeked, executions,
rows_processed, buffer_gets
FROM v$sql_cs_statistics
WHERE sql_id ='95jktg3mza0qm'
Bind Peeking + Adaptive Cursors
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 1.23 21.71 35341 35346 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 1.23 21.72 35341 35346 0 1
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 82
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=35346 pr=35341 pw=35341 time=0 us)
1991051 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=414975 us
cost=9652 size=15700664 card=1962583)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
direct path read 314 0.42 19.45
SQL*Net message from client 2 0.10 0.10
********************************************************************************
Bind Peeking + Adaptive Cursors in 11g
Statements with bind variables (+histograms) are bind sensitive
The first time you execute a statement with different selectivity it
uses the original plan
The second time it changes the plan and become bind aware
New values will use a plan for the appropriate selectivity range
Adaptive Cursors Views
V$SQL
V$SQL_CS_SELECTIVITY
Adaptive Cursors Views
V$SQL_CS_HISTOGRAM
V$SQL_CS_STATISTICS
PLSQL has soft parse avoidance
Implicit cursor
Explicit cursor
Native dynamic SQL
Ref cursor
Session_cached_cursors = 0
Ref cursors
No default adaptive cursor functionality in a session
Default adaptive cursor functionality in a session
Once another session executes the statement it will adapt
Adaptive Cursors Functionality
Bind variable with Equality and Histogram
Not for range conditions
Bind variable with Equality and Histogram
Range conditions
Does not support LIKE
/*+ BIND_AWARE */
Adaptive Cursors 11.1.0.6
Adaptive Cursors 11.1.0.7 and 11.2
So where are we now?
Our own code – works properly first time with hint
in SQL and PL/SQL
Software Packages – will still get it wrong once
and won’t use adaptive cursors for PL/SQL
at all within one session
unless we set session cached cursors =0
or ref cursors
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
The Cost Based Optimiser in 11gR2
xxxxxxxxxxxxxxxxxxxxx
Maybe you should buy an
Exadata box
So Much Promise
And then the
disappointment
Bind Peeking + Adaptive Cursors Summary
Your code
Packages
Minimise statement invalidations
Consider running the statement with minority and majority value on start up
Use the BIND_AWARE hint (SQL and PL/SQL) for skewed data
Use ref cursors (if hints are not allowed)
PL/SQL – set session_cached_cursors = 0 (temporarily)
Adaptive Cursors What we Really Need
Once a statement has been bind aware it knows next time
its parsed
Adaptive Cursors Persistence
Try to get rid of your hints
_optimizer_ignore_hints
Create additional statistics
Set _optimizer_ignore_hints to TRUE
Test the app
If it runs OK remove your hints
68 New Hints
SELECT name, inverse, sql_feature, version
FROM v$sql_hint
WHERE version like '11%'
ORDER BY version desc, name
New Hints
Much More Query Transformation
SELECT e.event_no, e.start_date, sum(cost) totcost
FROM events_large e, bookings_large b
WHERE e.event_no = b.event_no
GROUP BY e.event_no, e.start_date
alter session set tracefile_identifier = Penny
alter session set events '10053 trace name context forever'
explain plan for
SELECT e.event_no, e.start_date, sum(cost) totcost
FROM events_large e, bookings_large b
WHERE e.event_no = b.event_no
GROUP BY e.event_no, e.start_date;
alter session set events '10053 trace name context off'
10G – JOIN before the GROUP BY
11G – GROUP BY before the JOIN
New Hints
MONITOR
NO_MONITOR
select /*+ MONITOR */
count(comments) from bookings ;
select DBMS_SQLTUNE.REPORT_SQL_MONITOR(
session_id=>sys_context('userenv','sid'),
report_level=>'ALL') as report
from dual;
Check the differences in plans
Upgrading
The Cost Based Optimiser in 11gR2
Results Cache
SGA
populate invalidate
Most recently
used
SQL/PL/SQL
SQL Query
Results Cache
Results Cache
PL/SQL Function
Results Cache
Most recently used result sets
Buffer Cache Library Cache
Most recently
data
Query Results Cache
RESULT_CACHE_MODE MANUAL
FORCE
/*+RESULT_CACHE */
/*+ NO_RESULT_CACHE */
SELECT /*+ RESULT_CACHE */
count(b.comments)
FROM train1.events_large e, train1.bookings_large b
WHERE e.org_id = :v1
AND e.event_no = b.event_no
AND e.comments = :v2;
PL/SQL Function Results Cache
CREATE OR REPLACE FUNCTION quantity_booked
(p_resource_code in resources.code%TYPE,p_event_date in date)
RETURN NUMBER
RESULT_CACHE
IS
v_total_booked number := 0;
BEGIN
SELECT sum(b.quantity)
INTO v_total_booked
FROM bookings b, events e
WHERE e.event_no = b.event_no
AND p_event_date between e.start_date and e.end_date
AND b.resource_code = p_resource_code;
RETURN (v_total_booked);
END;
Monitoring the Results Cache
SELECT * FROM v$result_cache_memory
SELECT * FROM v$result_cache_objects
SELECT * FROM v$result_cache_statistics
SELECT * FROM v$result_cache_dependency
RESULT_CACHE_MAX_SIZE
RESULT_CACHE_MAX_RESULT
Explain Plan
CBO - Instability
CBO
?access
path
decision
System parameters
Session parameters
Optimiser StatisticsIndexes
SQL Profile
Software version
System statistics
DBA playing around
CBO - Instability
– Leave it all alone
– SQL Plan Management
– Store plan baseline
– Plans not used till accepted
– Manually accept or
– Allow Oracle to evolve plans
Solution 1
Solution 2
SQL Plan Management
Manual capture
DBMS_SPM.LOAD_PLANS_FROM_SQLSET
DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE
Auto capture of repeatable statements
OPTIMIZER_CAPTURE_SQL_PLAN_BASELINE = TRUE
Baseline =
(Stored and Accepted plans)
SQL Management Base
New Plan
identified during
execution
Stored not accepted
SQL Tuning Advisor identifies new
plan – SQL*Profile accepted
Auto accept of new plan
(if it performs better)
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE
Manual load/accept of new plan
DBMS_SPM.LOAD_PLANS_FROM_SQLSET
DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE
The Cost Based Optimiser in 11gR2
SAGE Computing Services
Customised Oracle Training Workshops and Consulting
Questions?
www.sagecomputing.com.au
penny@sagecomputing.com.au

More Related Content

PPTX
Finding SQL execution outliers
PDF
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
PDF
Deep review of LMS process
PDF
Percona live-2012-optimizer-tuning
PDF
New Tuning Features in Oracle 11g - How to make your database as boring as po...
DOCX
Exadata - Smart Scan Testing
PDF
SQLăƒăƒ„ăƒŒăƒ‹ăƒłă‚°ç·ćˆèšș療Oracle CloudWorldć‡șćŒ”æ‰€
PDF
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLăƒăƒ„ăƒŒăƒ‹ăƒłă‚°ç·ćˆèšșç™‚æ‰€ă€€ă‚±ăƒŒă‚čăƒ•ă‚Ąă‚€ăƒ«X
Finding SQL execution outliers
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
Deep review of LMS process
Percona live-2012-optimizer-tuning
New Tuning Features in Oracle 11g - How to make your database as boring as po...
Exadata - Smart Scan Testing
SQLăƒăƒ„ăƒŒăƒ‹ăƒłă‚°ç·ćˆèšș療Oracle CloudWorldć‡șćŒ”æ‰€
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLăƒăƒ„ăƒŒăƒ‹ăƒłă‚°ç·ćˆèšșç™‚æ‰€ă€€ă‚±ăƒŒă‚čăƒ•ă‚Ąă‚€ăƒ«X

What's hot (20)

PDF
E34 : [JPOUG Presents] Oracle Database ăźéš ă•ă‚ŒăŠă„ă‚‹æ§˜ă€…ăȘèŹŽă‚’è§Łăă‚»ăƒƒă‚·ăƒ§ăƒłă€ŒăȘăƒŒă‚“ă§ă ïŒŸă€ć†ăł @ db tec...
PDF
Demystifying cost based optimization
PDF
Chasing the optimizer
PDF
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
PDF
Same plan different performance
PDF
á„†á…©á†Œá„€á…©á„ƒá…”á„‡á…”á„‰á…Ąá„‹á…­á†Œá„Œá…Ąá„€á…­á„‹á…Čᆹ2ᄋᅔᆯ처 v0.5
PDF
Riyaj: why optimizer_hates_my_sql_2010
PDF
Oracle statistics by example
PDF
MariaDB: Engine Independent Table Statistics, including histograms
PDF
Histograms in 12c era
PDF
MySQL SQL Tutorial
PDF
PoC Oracle Exadata - Retour d'expérience
PDF
M|18 Querying Data at a Previous Point in Time
PDF
neutronæ”‹èŻ•äŸ‹ć­
PDF
pstack, truss etc to understand deeper issues in Oracle database
PDF
Performance tuning a quick intoduction
PDF
Bind Peeking - The Endless Tuning Nightmare
PDF
DataStax: A deep look at the CQL WHERE clause
PPTX
A deep look at the cql where clause
PDF
Rac 12c optimization
E34 : [JPOUG Presents] Oracle Database ăźéš ă•ă‚ŒăŠă„ă‚‹æ§˜ă€…ăȘèŹŽă‚’è§Łăă‚»ăƒƒă‚·ăƒ§ăƒłă€ŒăȘăƒŒă‚“ă§ă ïŒŸă€ć†ăł @ db tec...
Demystifying cost based optimization
Chasing the optimizer
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
Same plan different performance
á„†á…©á†Œá„€á…©á„ƒá…”á„‡á…”á„‰á…Ąá„‹á…­á†Œá„Œá…Ąá„€á…­á„‹á…Čᆹ2ᄋᅔᆯ처 v0.5
Riyaj: why optimizer_hates_my_sql_2010
Oracle statistics by example
MariaDB: Engine Independent Table Statistics, including histograms
Histograms in 12c era
MySQL SQL Tutorial
PoC Oracle Exadata - Retour d'expérience
M|18 Querying Data at a Previous Point in Time
neutronæ”‹èŻ•äŸ‹ć­
pstack, truss etc to understand deeper issues in Oracle database
Performance tuning a quick intoduction
Bind Peeking - The Endless Tuning Nightmare
DataStax: A deep look at the CQL WHERE clause
A deep look at the cql where clause
Rac 12c optimization
Ad

Viewers also liked (9)

PPTX
Geocaching 101: Making Connections to Your Curriculum
PDF
Commodore headlights2
PPTX
Financial Advice Provided By Financial Wisdom
PPTX
Holden Commodore - Campaign Pitch Presentation
PPTX
Robo-advice: Is this the future?
 
PPTX
FinTech Belgium - Impact of robo-advice on wealth management - MeDirect Bank
PPTX
Fp&a operating model
PPT
Cost Based Optimizer - Part 2 of 2
PPT
Team Building & Team Work
Geocaching 101: Making Connections to Your Curriculum
Commodore headlights2
Financial Advice Provided By Financial Wisdom
Holden Commodore - Campaign Pitch Presentation
Robo-advice: Is this the future?
 
FinTech Belgium - Impact of robo-advice on wealth management - MeDirect Bank
Fp&a operating model
Cost Based Optimizer - Part 2 of 2
Team Building & Team Work
Ad

Similar to The Cost Based Optimiser in 11gR2 (20)

PDF
Meet the CBO in Version 11g
PPSX
Cost Based Oracle
PPTX
Top 10 tips for Oracle performance
PPTX
Embarcadero In Search of Plan Stability Part 1 Webinar Slides
PPT
Optimizer in oracle 11g by wwf from ebay COC
PDF
Postgres performance for humans
PPTX
Oracle Query Optimizer - An Introduction
PPTX
Oracle performance tuning_sfsf
PPTX
Further Adventures With ASH
PPT
Cost Based Optimizer - Part 1 of 2
PDF
Hailey_Database_Performance_Made_Easy_through_Graphics.pdf
PDF
query_tuning.pdf
PDF
Query optimizer vivek sharma
PDF
Results cache
PPTX
SQL Server 2012 Best Practices
PPTX
Introduction to oracle optimizer
PDF
In Search of Plan Stability - Part 1
PDF
Database and application performance vivek sharma
PPTX
DB
PDF
Cbo100053
Meet the CBO in Version 11g
Cost Based Oracle
Top 10 tips for Oracle performance
Embarcadero In Search of Plan Stability Part 1 Webinar Slides
Optimizer in oracle 11g by wwf from ebay COC
Postgres performance for humans
Oracle Query Optimizer - An Introduction
Oracle performance tuning_sfsf
Further Adventures With ASH
Cost Based Optimizer - Part 1 of 2
Hailey_Database_Performance_Made_Easy_through_Graphics.pdf
query_tuning.pdf
Query optimizer vivek sharma
Results cache
SQL Server 2012 Best Practices
Introduction to oracle optimizer
In Search of Plan Stability - Part 1
Database and application performance vivek sharma
DB
Cbo100053

More from Sage Computing Services (13)

PDF
Oracle XML DB - What's in it for me?
PDF
Aspects of 10 Tuning
PPT
Back to basics: Simple database web services without the need for SOA
PDF
Whose fault is it? - a review of application tuning problems
PDF
Lost without a trace
PDF
How Can I tune it When I Can't Change the Code?
PDF
Take a load off! Load testing your Oracle APEX or JDeveloper web applications
PDF
Transformations - how Oracle rewrites your statements
PDF
Application Express - A web development environment for the masses - and for ...
PPTX
OHarmony - How the Optimiser works
PPTX
Common Coding and Design mistakes (that really mess up performance)
PPTX
Oracle Discoverer is dead - Where to next for BI?
Oracle XML DB - What's in it for me?
Aspects of 10 Tuning
Back to basics: Simple database web services without the need for SOA
Whose fault is it? - a review of application tuning problems
Lost without a trace
How Can I tune it When I Can't Change the Code?
Take a load off! Load testing your Oracle APEX or JDeveloper web applications
Transformations - how Oracle rewrites your statements
Application Express - A web development environment for the masses - and for ...
OHarmony - How the Optimiser works
Common Coding and Design mistakes (that really mess up performance)
Oracle Discoverer is dead - Where to next for BI?

Recently uploaded (20)

PPTX
history of c programming in notes for students .pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Nekopoi APK 2025 free lastest update
PDF
Understanding Forklifts - TECH EHS Solution
PDF
top salesforce developer skills in 2025.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
 
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Introduction to Artificial Intelligence
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
history of c programming in notes for students .pptx
Wondershare Filmora 15 Crack With Activation Key [2025
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Nekopoi APK 2025 free lastest update
Understanding Forklifts - TECH EHS Solution
top salesforce developer skills in 2025.pdf
How Creative Agencies Leverage Project Management Software.pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
PTS Company Brochure 2025 (1).pdf.......
Softaken Excel to vCard Converter Software.pdf
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
 
Which alternative to Crystal Reports is best for small or large businesses.pdf
How to Choose the Right IT Partner for Your Business in Malaysia
Introduction to Artificial Intelligence
CHAPTER 2 - PM Management and IT Context
2025 Textile ERP Trends: SAP, Odoo & Oracle

The Cost Based Optimiser in 11gR2

  • 1. www.sagecomputing.com.au penny@sagecomputing.com.au the Cost Based Optimiser in 11g Rel 2 Penny Cookson SAGE Computing Services SAGE Computing Services Customised Oracle Training Workshops and Consulting
  • 2. SAGE Computing Services Customised Oracle Training Workshops and Consulting Penny Cookson Managing Director and Principal Consultant Working with Oracle products since 1987 Oracle Magazine Educator of the Year 2004 www.sagecomputing.com.au penny@sagecomputing.com.au
  • 3. Agenda Extended Statistics Kernel trace granularity - oradebug Cardinality Feedback Adaptive Cursors New behaviours Hints in 11g Getting rid of your hints Assessing plan changes on upgrade Results cache
  • 4. S
  • 6. Multi Column Statistics Gather statistics on combinations of columns Improves plans for complex dependency patterns (and this is persistent) SELECT count(b.comments) FROM train.events_large e, train.bookings_large b WHERE e.org_id = 2264 AND e.event_no = b.event_no AND e.comments = 'TEST'
  • 7. Multi Column Data Patterns SELECT count(*) FROM train.events_large e SELECT count(*) FROM train.events_large e WHERE e.org_id = 2264 SELECT count(e.comments) FROM train.events_large e WHERE e.comments = 'TEST' SELECT count(e.comments) FROM train.events_large e WHERE e.comments = 'TEST‘ AND e.org_id = 2264
  • 8. With Individual Statistics call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 5.00 22.52 35341 36337 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 5.00 22.52 35341 36337 0 1 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: 82 Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=36337 pr=35341 pw=35341 time=0 us) 175 HASH JOIN (cr=36337 pr=35341 pw=35341 time=13 us cost=9966 size=33365083 card=1076293) 4 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=3 us cost=274 size=319770 card=18810) 5767168 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=225583 us cost=9665 size=80740352 card=5767168) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 direct path read 314 0.38 15.88 resmgr:cpu quantum 11 0.14 0.27 SQL*Net message from client 2 0.04 0.04 ********************************************************************************
  • 9. Auto Created Column Statistics BEGIN dbms_stats.gather_table_stats(ownname=>'TRAI1N', tabname=>'EVENTS_LARGE', cascade=>TRUE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', no_invalidate=>FALSE); END; SELECT column_name, histogram, num_buckets FROM user_tab_col_statistics WHERE table_name = 'EVENTS_LARGE'
  • 10. Auto Created Column Statistics SELECT extension_name, extension FROM user_stat_extensions WHERE table_name='EVENTS_LARGE‘ So same access path used ******************************************************************************** Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=36337 pr=35341 pw=35341 time=0 us) 175 HASH JOIN (cr=36337 pr=35341 pw=35341 time=13 us cost=9966 size=33365083 card=1076293) 4 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=3 us cost=274 size=319770 card=18810) 5767168 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=225583 us cost=9665 size=80740352 card=5767168)
  • 11. Manually Create Multi Column Statistics BEGIN dbms_stats.gather_table_stats(ownname=>'TRAIN', tabname=>'EVENTS_LARGE', cascade=>TRUE, method_opt => 'FOR COLUMNS (org_id, comments) SIZE SKEWONLY', no_invalidate=>FALSE); END; OR dbms_stats.create_extended_stats('TRAIN1','EVENTS_LARGE','(OR G_ID,COMMENTS)'); --(Then gather stats) SELECT extension_name, extension FROM user_stat_extensions WHERE table_name='EVENTS_LARGE'
  • 12. Manually Create Multi Column Statistics SELECT column_name, histogram, num_buckets FROM user_tab_col_statistics WHERE table_name = 'EVENTS_LARGE'
  • 13. Multi Column Statistics ******************************************************************************** SELECT count(b.comments) FROM train.events_large e, train.bookings_large b WHERE e.org_id = 2264 AND e.event_no = b.event_no AND e.comments = 'TEST' call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.01 0.01 0 1175 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.01 0.01 0 1175 0 1 Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=1175 pr=0 pw=0 time=0 us) 175 NESTED LOOPS (cr=1175 pr=0 pw=0 time=71 us) 175 NESTED LOOPS (cr=1001 pr=0 pw=0 time=39 us cost=1129 size=26815 card=865) 4 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=4 us cost=274 size=255 card=15) 175 INDEX RANGE SCAN BK_EVT2 (cr=10 pr=0 pw=0 time=10 us cost=2 size=0 card=57)(object id 69868) 175 TABLE ACCESS BY INDEX ROWID BOOKINGS_LARGE (cr=174 pr=0 pw=0 time=0 us cost=57 size=798 card=57) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 SQL*Net message from client 2 0.02 0.02 ********************************************************************************
  • 14. Multi Column Statistics ******************************************************************************** SELECT count(b.comments) FROM train.organisations o, train.events_large e, train.bookings_large b, train.resources r WHERE o.org_id = e.org_id AND e.event_no = b.event_no AND b.resource_code = r.code AND o.name = 'Australian Medical Systems' AND r.description = 'Buffet Lunch' AND e.comments = 'TEST' call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 4.64 21.66 35341 36351 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 4.64 21.66 35341 36351 0 1 Misses in library cache during parse: 0 Optimizer mode: ALL_ROWS Parsing user id: 82
  • 15. Multi Column Statistics ******************************************************************************** Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=36351 pr=35341 pw=35341 time=0 us) 25 HASH JOIN (cr=36351 pr=35341 pw=35341 time=1966789 us cost=9972 size=6555490 card=79945) 4 HASH JOIN (cr=1005 pr=0 pw=0 time=8 us cost=281 size=792225 card=12575) 1 MERGE JOIN CARTESIAN (cr=14 pr=0 pw=0 time=0 us cost=6 size=46 card=1) 1 TABLE ACCESS FULL ORGANISATIONS (cr=7 pr=0 pw=0 time=0 us cost=3 size=26 card=1) 1 BUFFER SORT (cr=7 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 1 TABLE ACCESS FULL RESOURCES (cr=7 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 75243 TABLE ACCESS FULL EVENTS_LARGE (cr=991 pr=0 pw=0 time=1020 us cost=274 size=1282616 card=75448) 5767168 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=350849 us cost=9665 size=109576192 card=5767168) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 direct path read 314 0.35 15.49 resmgr:cpu quantum 2 0.12 0.12 SQL*Net message from client 2 0.04 0.05 ********************************************************************************
  • 16. Multi Column Statistics - Summary Manually create column groups and statistics on them Complex joins may still need SQL Profiles Use for dependent column such as Country, State Use DBMS_STATS.SEED_COL_USAGE to gather column usage stats Use DBMS_STATS.REPORT_COL_USAGE to report on col usage stats
  • 17. Gathering Statistics - Preferences
  • 18. Setting Statistics Gathering Defaults Obsolete: GET_PARAM SET_PARAM Procedure Use: GET_PREFS Function SET_TABLE_PREFS (set for individual tables) SET_GLOBAL_PREFS – for new objects
  • 19. Table Prefs PROCEDURE SET_TABLE_PREFS Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- OWNNAME VARCHAR2 IN TABNAME VARCHAR2 IN PNAME VARCHAR2 IN PVALUE VARCHAR2 IN PNAME CASCADE DEGREE ESTIMATE_PERCENT METHOD_OPT NO_INVALIDATE GRANULARITY PUBLISH INCREMENTAL (only scan partitions that have been changed) STALE_PERCENT
  • 23. Gathering and Publishing Set preferences to PUBLISH = ‘FALSE’ Gather Statistics user_tab_pending_stats user_ind_pending_stats user_col_pending_stats Run test case Alter session set optimizer_pending_statistics = TRUE Run test case Worse Better dbms_stats. delete_pending_stats dbms_stats. publish_pending_stats user_tab_statistics user_ind_statistics user_tab_col_statistics
  • 24. Gathering and Publishing SELECT obj#, TO_CHAR(savtime,'dd/mm/yyyy') save_time, rowcnt, blkcnt, avgrln, samplesize, analyzetime FROM wri$_optstat_tab_history ORDER BY savtime desc
  • 25. Gathering and Publishing Never publish any statistics until you are happy they work better
  • 26. Trace Granularity Oracle 11g: Improved Oracle diagnostic event infrastructure ORADEBUG DOC
  • 27. Tracing SQL Executions ALTER SESSION SET EVENTS 'sql_trace[SQL: 324dr9k932njj] plan_stat=all_executions,wait=true,bind=true'; SELECT count(b.comments) FROM events_large e, bookings_large b WHERE e.org_id = 2264 AND e.event_no = b.event_no AND e.comments = 'TEST' Execute this twice and format the trace file ora11_ora_5852_324dr9k932njj.rtf.
  • 28. Cardinality Feedback We have been able to find information about this with dbms_xplan since 10g: Real cardinality v expected cardinality?
  • 29. Cardinality Feedback SELECT /*+ GATHER_PLAN_STATISTICS */ count(b.comments) FROM events_large e, bookings_large b WHERE e.org_id = 2264 AND e.event_no = b.event_no AND e.comments = 'TEST' SELECT DBMS_XPLAN.DISPLAY_CURSOR (FORMAT=>'ALLSTATS LAST') FROM dual;
  • 30. Cardinality Feedback SYS.DBMS_XPLAN_TYPE('SQL_ID 2yxvxc5r9z6tv, child number 0') SYS.DBMS_XPLAN_TYPE('-------------------------------------') SYS.DBMS_XPLAN_TYPE('SELECT /*+ GATHER_PLAN_STATISTICS */ count(b.comments) FROM ') SYS.DBMS_XPLAN_TYPE('events_large e, bookings_large b WHERE e.org_id = 2264 AND e.event_no ') SYS.DBMS_XPLAN_TYPE('= b.event_no AND e.comments = 'TEST'') SYS.DBMS_XPLAN_TYPE(' ') SYS.DBMS_XPLAN_TYPE('Plan hash value: 3269294976') SYS.DBMS_XPLAN_TYPE(' ') SYS.DBMS_XPLAN_TYPE('---------------------------------------------------------------------------------------------------------- --------------------------') SYS.DBMS_XPLAN_TYPE('| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |') SYS.DBMS_XPLAN_TYPE('---------------------------------------------------------------------------------------------------------- --------------------------') SYS.DBMS_XPLAN_TYPE('| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:02.23 | 36451 | 741 | | | |') SYS.DBMS_XPLAN_TYPE('| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:02.23 | 36451 | 741 | | | |') SYS.DBMS_XPLAN_TYPE('|* 2 | HASH JOIN | | 1 | 398K| 232 |00:00:13.89 | 36451 | 741 | 1452K| 1452K| 630K (0)|') SYS.DBMS_XPLAN_TYPE('|* 3 | TABLE ACCESS FULL| EVENTS_LARGE | 1 | 6967 | 4 |00:00:00.01 | 992 | 0 | | | |') SYS.DBMS_XPLAN_TYPE('| 4 | TABLE ACCESS FULL| BOOKINGS_LARGE | 1 | 5767K| 5767K|00:00:01.64 | 35459 | 741 | | | |') SYS.DBMS_XPLAN_TYPE('---------------------------------------------------------------------------------------------------------- --------------------------') SYS.DBMS_XPLAN_TYPE(' ') SYS.DBMS_XPLAN_TYPE('Predicate Information (identified by operation id):') SYS.DBMS_XPLAN_TYPE('---------------------------------------------------') SYS.DBMS_XPLAN_TYPE(' ') SYS.DBMS_XPLAN_TYPE(' 2 - access("E"."EVENT_NO"="B"."EVENT_NO")') SYS.DBMS_XPLAN_TYPE(' 3 - filter(("E"."ORG_ID"=2264 AND "E"."COMMENTS"='TEST'))') SYS.DBMS_XPLAN_TYPE(' ')
  • 31. Cardinality Feedback Cursor Cache Execute the SQL Cursor Cache Parse the SQL Transform Estimate cost Generate execution plan
  • 32. Cardinality Feedback If it has to do this it has got it wrong once and Its not persistent so it will keep getting it wrong once
  • 33. Cardinality Feedback Create your statistics so Oracle does not need to do this dbms_stats.create_extended_stats ('TRAIN1','EVENTS_LARGE','(ORG_ID,COMMENTS)'); SELECT count(b.comments) FROM events_large e, bookings_large b WHERE e.org_id = 2264 AND e.event_no = b.event_no AND e.comments = 'TEST'
  • 34. Cardinality Feedback Set optimizer_dynamic_sampling so Oracle does not need to do this SELECT /*+ dynamic_sampling (4) */ count(b.comments) FROM events_large e, bookings_large b WHERE e.org_id = 2264 AND e.event_no = b.event_no AND e.comments = 'TEST'
  • 35. Cardinality Feedback No use across multiple tables SELECT count(b.comments) FROM organisations o, events_large e, bookings_large b WHERE o.org_id = e.org_id AND e.event_no = b.event_no AND o.name = 'Australian Medical Systems' AND e.comments = 'TEST'
  • 36. Cardinality Feedback Use optimizer_scaling to correct multi table estimates SELECT /*+ opt_estimate(JOIN,("E","O"), SCALE_ROWS= 0.000001) */ count(b.comments) FROM organisations o, events_large e, bookings_large b WHERE o.org_id = e.org_id AND e.event_no = b.event_no AND o.name = 'Australian Medical Systems' AND e.comments = 'TEST'
  • 38. Cardinality Feedback Oracle asking Did I get it right? Need stable data patterns Can use where poor stats and no dynamic sampling Designed to correct mistakes Not for bind variables Only once per plan Not persistent
  • 39. A Characteristic Problem I haven’t changed anything Its really slow this morning I did the same thing yesterday and it was fine Actually its OK now No its not Thank you so much you’ve fixed it (I haven’t done anything)
  • 40. Bind Peeking + Adaptive Cursors SELECT resource_code, count(*) FROM bookings_large GROUP BY resource_code; Majority value Minority value
  • 41. Bind Peeking Look at the value of the bind variable when the statement is parsed Plan is based on that value BEGIN :v3 := ‘PC1'; END; SELECT COUNT(quantity) FROM bookings_large WHERE resource_code = :v3; BEGIN :v3 := ‘BRLG'; END; SELECT COUNT(quantity) FROM bookings_large WHERE resource_code = :v3; SAME PLAN STILL INDEX for 34% of rows INDEX for <1% of rows
  • 42. Bind Peeking + Adaptive Cursors SELECT COUNT(l.quantity) FROM train.bookings_large l WHERE resource_code = :v1 SELECT sql_id FROM v$sqlarea WHERE sql_text = 'SELECT COUNT(l.quantity) FROM train.bookings_large l WHERE resource_code = :v1'
  • 43. Bind Peeking + Adaptive Cursors BEGIN :v1 := 'PC1'; END; SELECT COUNT(l.quantity) FROM train.bookings_large l WHERE resource_code = :v1 SELECT sql_id, child_number, is_bind_sensitive, is_bind_aware FROM v$sql WHERE sql_id ='95jktg3mza0qm'; IS_BIND_SENSITIVE - may need to change the plan - set on first execution of the statement IS_BIND_AWARE - do need to change the plan
  • 44. Bind Peeking + Adaptive Cursors SELECT child_number, bind_set_hash_value, peeked, executions, rows_processed, buffer_gets FROM v$sql_cs_statistics WHERE sql_id ='95jktg3mza0qm'
  • 45. Bind Peeking + Adaptive Cursors call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.01 0.01 0 0 0 0 Fetch 2 0.12 0.43 119 6635 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.14 0.44 119 6635 0 1 Misses in library cache during parse: 1 Misses in library cache during execute: 1 Optimizer mode: ALL_ROWS Parsing user id: 82 Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=6635 pr=119 pw=119 time=0 us) 48510 TABLE ACCESS BY INDEX ROWID BOOKINGS_LARGE (cr=6635 pr=119 pw=119 time=2870 us cost=1977 size=316008 card=39501) 48510 INDEX RANGE SCAN BK_RES2 (cr=104 pr=0 pw=0 time=527 us cost=90 size=0 card=39501)(object id 69870) ******************************************************************************** Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 SQL*Net message from client 2 0.00 0.00 ********************************************************************************
  • 46. Bind Peeking + Adaptive Cursors BEGIN :v1 := ‘BRLG'; END; SELECT COUNT(l.quantity) FROM train.bookings_large l WHERE resource_code = :v1 SELECT sql_id, child_number, is_bind_sensitive, is_bind_aware FROM v$sql WHERE sql_id ='95jktg3mza0qm';
  • 47. Bind Peeking + Adaptive Cursors SELECT child_number, bind_set_hash_value, peeked, executions, rows_processed, buffer_gets FROM v$sql_cs_statistics WHERE sql_id ='95jktg3mza0qm'
  • 48. Bind Peeking + Adaptive Cursors call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 6.29 78.82 34335 39594 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 6.29 78.82 34335 39594 0 1 Misses in library cache during parse: 0 Optimizer mode: ALL_ROWS Parsing user id: 82 Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=39594 pr=34335 pw=34335 time=0 us) 1991051 TABLE ACCESS BY INDEX ROWID BOOKINGS_LARGE (cr=39594 pr=34335 pw=34335 time=626800 us cost=1977 size=316008 card=39501) 1991051 INDEX RANGE SCAN BK_RES2 (cr=4437 pr=4436 pw=4436 time=61616 us cost=90 size=0 card=39501)(object id 69870) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 db file sequential read 34335 0.29 72.08 resmgr:cpu quantum 30 0.10 1.29 SQL*Net message from client 2 0.00 0.00
  • 49. Bind Peeking + Adaptive Cursors BEGIN :v1 := ‘BRLG'; END; SELECT COUNT(l.quantity) FROM train.bookings_large l WHERE resource_code = :v1 SELECT sql_id, child_number, is_bind_sensitive, is_bind_aware FROM v$sql WHERE sql_id ='95jktg3mza0qm';
  • 50. Bind Peeking + Adaptive Cursors SELECT child_number, bind_set_hash_value, peeked, executions, rows_processed, buffer_gets FROM v$sql_cs_statistics WHERE sql_id ='95jktg3mza0qm'
  • 51. Bind Peeking + Adaptive Cursors call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 1.23 21.71 35341 35346 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 1.23 21.72 35341 35346 0 1 Misses in library cache during parse: 0 Misses in library cache during execute: 1 Optimizer mode: ALL_ROWS Parsing user id: 82 Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=35346 pr=35341 pw=35341 time=0 us) 1991051 TABLE ACCESS FULL BOOKINGS_LARGE (cr=35346 pr=35341 pw=35341 time=414975 us cost=9652 size=15700664 card=1962583) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 direct path read 314 0.42 19.45 SQL*Net message from client 2 0.10 0.10 ********************************************************************************
  • 52. Bind Peeking + Adaptive Cursors in 11g Statements with bind variables (+histograms) are bind sensitive The first time you execute a statement with different selectivity it uses the original plan The second time it changes the plan and become bind aware New values will use a plan for the appropriate selectivity range
  • 55. PLSQL has soft parse avoidance Implicit cursor Explicit cursor Native dynamic SQL Ref cursor Session_cached_cursors = 0 Ref cursors No default adaptive cursor functionality in a session Default adaptive cursor functionality in a session Once another session executes the statement it will adapt
  • 56. Adaptive Cursors Functionality Bind variable with Equality and Histogram Not for range conditions Bind variable with Equality and Histogram Range conditions Does not support LIKE /*+ BIND_AWARE */ Adaptive Cursors 11.1.0.6 Adaptive Cursors 11.1.0.7 and 11.2
  • 57. So where are we now? Our own code – works properly first time with hint in SQL and PL/SQL Software Packages – will still get it wrong once and won’t use adaptive cursors for PL/SQL at all within one session unless we set session cached cursors =0 or ref cursors
  • 67. So Much Promise And then the disappointment
  • 68. Bind Peeking + Adaptive Cursors Summary Your code Packages Minimise statement invalidations Consider running the statement with minority and majority value on start up Use the BIND_AWARE hint (SQL and PL/SQL) for skewed data Use ref cursors (if hints are not allowed) PL/SQL – set session_cached_cursors = 0 (temporarily)
  • 69. Adaptive Cursors What we Really Need Once a statement has been bind aware it knows next time its parsed Adaptive Cursors Persistence
  • 70. Try to get rid of your hints _optimizer_ignore_hints Create additional statistics Set _optimizer_ignore_hints to TRUE Test the app If it runs OK remove your hints
  • 71. 68 New Hints SELECT name, inverse, sql_feature, version FROM v$sql_hint WHERE version like '11%' ORDER BY version desc, name New Hints
  • 72. Much More Query Transformation SELECT e.event_no, e.start_date, sum(cost) totcost FROM events_large e, bookings_large b WHERE e.event_no = b.event_no GROUP BY e.event_no, e.start_date alter session set tracefile_identifier = Penny alter session set events '10053 trace name context forever' explain plan for SELECT e.event_no, e.start_date, sum(cost) totcost FROM events_large e, bookings_large b WHERE e.event_no = b.event_no GROUP BY e.event_no, e.start_date; alter session set events '10053 trace name context off'
  • 73. 10G – JOIN before the GROUP BY
  • 74. 11G – GROUP BY before the JOIN
  • 75. New Hints MONITOR NO_MONITOR select /*+ MONITOR */ count(comments) from bookings ; select DBMS_SQLTUNE.REPORT_SQL_MONITOR( session_id=>sys_context('userenv','sid'), report_level=>'ALL') as report from dual;
  • 76. Check the differences in plans Upgrading
  • 78. Results Cache SGA populate invalidate Most recently used SQL/PL/SQL SQL Query Results Cache Results Cache PL/SQL Function Results Cache Most recently used result sets Buffer Cache Library Cache Most recently data
  • 79. Query Results Cache RESULT_CACHE_MODE MANUAL FORCE /*+RESULT_CACHE */ /*+ NO_RESULT_CACHE */ SELECT /*+ RESULT_CACHE */ count(b.comments) FROM train1.events_large e, train1.bookings_large b WHERE e.org_id = :v1 AND e.event_no = b.event_no AND e.comments = :v2;
  • 80. PL/SQL Function Results Cache CREATE OR REPLACE FUNCTION quantity_booked (p_resource_code in resources.code%TYPE,p_event_date in date) RETURN NUMBER RESULT_CACHE IS v_total_booked number := 0; BEGIN SELECT sum(b.quantity) INTO v_total_booked FROM bookings b, events e WHERE e.event_no = b.event_no AND p_event_date between e.start_date and e.end_date AND b.resource_code = p_resource_code; RETURN (v_total_booked); END;
  • 81. Monitoring the Results Cache SELECT * FROM v$result_cache_memory SELECT * FROM v$result_cache_objects SELECT * FROM v$result_cache_statistics SELECT * FROM v$result_cache_dependency RESULT_CACHE_MAX_SIZE RESULT_CACHE_MAX_RESULT Explain Plan
  • 82. CBO - Instability CBO ?access path decision System parameters Session parameters Optimiser StatisticsIndexes SQL Profile Software version System statistics DBA playing around
  • 83. CBO - Instability – Leave it all alone – SQL Plan Management – Store plan baseline – Plans not used till accepted – Manually accept or – Allow Oracle to evolve plans Solution 1 Solution 2
  • 84. SQL Plan Management Manual capture DBMS_SPM.LOAD_PLANS_FROM_SQLSET DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE Auto capture of repeatable statements OPTIMIZER_CAPTURE_SQL_PLAN_BASELINE = TRUE Baseline = (Stored and Accepted plans) SQL Management Base New Plan identified during execution Stored not accepted SQL Tuning Advisor identifies new plan – SQL*Profile accepted Auto accept of new plan (if it performs better) DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE Manual load/accept of new plan DBMS_SPM.LOAD_PLANS_FROM_SQLSET DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE
  • 86. SAGE Computing Services Customised Oracle Training Workshops and Consulting Questions? www.sagecomputing.com.au penny@sagecomputing.com.au