Vous êtes sur la page 1sur 44

Oracle Optimizer Bootcamp 10 Optimizer tips you can't do without

Maria Colgan & Jonathan Lewis

PART 2
2 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Program Agenda
Using the right tools Finding the right sample size Tell the optimizer everything Functions friends or foe Most useful hints to know

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Tell the Optimizer everything


The Optimizer makes assumptions in certain case
Each additional where clause predicates reduces the number of rows Each additional group by column will increase number of rows returned Applying a function to column will alter the NDV of the column

Sometimes you know more about your data than basic statistics show
Best way to get a good plan is to tell the Optimizer everything Otherwise it assumes, making an ass out of u and me

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Tell the optimizer everything


Correlated column example
SELECT * FROM vehicles WHERE model = 530xi

AND
MAKE BMW

color = 'RED;
MODEL 530xi COLOR RED Year 2013

Cardinality = #ROWS * 1 * 1 => 12 * 1 * 1 = 1 NDV c1 NDV c2 4 3

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Tell the optimizer everything


Correlated column example
SELECT * FROM vehicles WHERE model = 530xi

AND
MAKE BMW BMW

make = BMW;
MODEL 530xi 530xi COLOR RED BLACK Year 2013 2011

BMW

530xi

BLUE

2012

Cardinality

#ROWS * 1 * 1 => 12 * 1 * 1 = 1 NDV c1 NDV c2 4 3

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Create extended statistics on column group


DBMS_STATS.CREATE_EXTENDED_STATS

New Column with system generated name

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Tell the optimizer everything


Correlated column example with extended statistics
SELECT * FROM vehicles WHERE model = 530xi AND
MAKE BMW BMW

make = BMW;
MODEL 530xi 530xi COLOR RED BLACK Year 2013 2011

BMW

530xi

BLUE

2012

Cardinality calculated using column group statistics

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Tell the Optimizer everything


Automatic column group detection

Use SEED_COL_USAGE to have Oracle monitor workload Can monitor STS or live system Recommends what column groups are needed based on workload

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Bad Defaults (a)


create table t1 as select decode( -- every 1000th row mod(rownum - 1,1000), -- is a 'null' date 0,to_date('31-Dec-4000'), to_date('01-Jan-2010') + trunc((rownum-1)/100) ) date_closed from large_data_source where -- 5 years in days * 100 rownum <= 1827 * 100 ;

10

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Bad Defaults (b)


select * from t1 where date_closed -- 36,500 between to_date('01-Jan-2012','dd-mon-yyyy') and to_date('31-Dec-2012','dd-mon-yyyy'); With simple statistics.
TABLE ACCESS (FULL) OF 'T1' (Cost=46 Card=291 Bytes=2328)
rows

With 11 column histogram (two per year and one for the garbage)
TABLE ACCESS (FULL) OF 'T1' (Cost=46 Card=36320 Bytes=290560)

With nulls and simple statistics.


TABLE ACCESS (FULL) OF 'T1' (Cost=46 Card=36583 Bytes=256081)

11

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Graphical Interpretation
Data for 2012

The real data

Oracle's first impression

Impression with histogram

12

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Bad Data Types (a)


create table t1 as select d1, to_number(to_char(d1,'yyyymmdd')) n1, to_char(d1,'yyyymmdd') v1 from ( select to_date('31-Dec-2009') + rownum d1 from all_objects where rownum <= 1827 -- 5 years, );
13 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

-- date -- numeric

-- char

daily

Bad Data Types (b)


select * from t1 where d1 -- 7 rows between to_date('30-Dec-2012','dd-mon-yyyy') and to_date('05-Jan-2013','dd-mon-yyyy'); On the date type.
TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=8 Bytes=184)

N1 between 20121230 and 20030105


TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=397 Bytes=9131)

V1 between ' 20121230' and '20030105'


TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=457 Bytes=10511)

10g+ gets Card=397 - everything looks like numbers)

14

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Histogram effects:

N1 between 20121230 and 20130105


pre-histogram post-histogram

TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=397 Bytes=9131) TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=32 Bytes=736)

V1 between ' 20121230' and '20130105


pre-histogram

TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=457 Bytes=10511)


post-histogram

TABLE ACCESS (FULL) OF 'T1' (Cost=3 Card=30 Bytes=690)


15 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Graphical Interpretation
The real (char/number) data

Oracle's first impression

Impression with histogram

16

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Program Agenda
Using the right tools Finding the right sample size Tell the optimizer everything Functions friends or foe Most useful hints to know

17

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Expected index range scan but got fast full index scan
Query How many packages of bounce did we sell?

SELECT count(*) FROM sales2 WHERE to_char(prod_id)=139;


Sales 2 has a b-tree index on the prod_id column

18

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Cardinality estimate is in the right ballpark so not a problem with statistics Why is an equality predicate being evaluated as a filter and not an access predicate? Could it have something to do with the TO_CHAR function

19

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?

INTERNAL_FUNCTION indicates Oracle needs to modify predicate


In this case a data type conversion occurred

Predicate is TO_CHAR(prod_id) Optimizer has no idea how function effects values in prod_id column Optimizer cant determine which rows will be accessed now

20

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


What data type is the prod_id column ?

But literal value is a character string 139

Better to apply inverse function on other side of predicate

21

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Solution - Use inverse function on other side of predicate Query rewrite
SELECT count(*)

FROM

sales2

WHERE prod_id=to_number(139);

22

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Using inverse function on other side of predicate
Keep the following in mind when deciding where to place the function
Try to place functions on top of constants (literals, binds) rather than on columns Avoid functions on index columns or partition keys as it prevents index use or

partition pruning
For function-based index to be considered, use that exact function as specified in

index
If multiple predicates involve the same columns, write predicates such that they

share common expressions For example,

WHERE f(a) = b
AND a=c

Should be rewritten as

WHERE a = inv_f(b)
AND a=c

This will allow transitive predicate c=inv_f(b) to be added by the optimizer

23

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Virtual Columns (a)


create Select table t1 as cast(rownum as number(8,0)) cast(rownum as number(8,0)) all_objects rownum <= 10000 id1, id2

from where ; alter table t1 add m2 generated always as ( mod(id2,3)) virtual ;

execute dbms_stats.gather_table_stats(user,'t1');

24

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Virtual Columns (b)


set autotrace traceonly explain select * from t1 where mod(id1,3) = 0; |* 1 | TABLE ACCESS FULL| T1 | 100 | 1100 | . 4 |

Predicate Information (identified by operation id): 1 - filter(MOD("ID1",3)=0) select * from t1 where mod(id1,3) != 0;

|*

1 |

TABLE ACCESS FULL| T1

500 |

5500 |

. 4 |

Predicate Information (identified by operation id): 1 - filter(MOD("ID1",3)<>0)


25 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Virtual Columns (c)


set autotrace traceonly explain select * from t1 where mod(id2,3) = 0; |* 1 | TABLE ACCESS FULL| T1 | 3333 | 36663 |

. 4 |

Predicate Information (identified by operation id): 1 - filter("T1"."M2"=0) select * from t1 where mod(id2,3) != 0; |* 1 | TABLE ACCESS FULL| T1 | 6667 | 73337 | . 4 |

Predicate Information (identified by operation id): 1 - filter("T1"."M2"<>0)

26

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Program Agenda
Using the right tools Finding the right sample size Tell the optimizer everything Functions friends or foe Most useful hints to know

27

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Most useful hints to know


Understanding Optimizer hints
Hints allow you to influence the Optimizer when it has to choose

between several possibilities A hint is a directive that will be followed when applicable
Can influence everything from the Optimizer mode used to each

operation in the execution


The hint mechanism is not exclusively used by the Optimizer
Some of the most useful hint influence SQL execution

28

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Most useful hints to know


GATHER_PLAN_STATISTICS hint
GATHER_PLAN_STATISTICS triggers execution time statistics to be

preserved Records actual number of rows seen for each operation (step) in plan Execution statistis displayed in plan when format parameter of DMBS_XPLAN set to ALLSTATS LAST
Means display all execution statistics for last execution of this cursor

29

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

GATHER_PLAN_STATISTICS hint

SELECT * FROM table ( DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST'));

Compare estimated rows returned for each operation to actual rows

30

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

GATHER_PLAN_STATISTICS Hint
SELECT * FROM table ( DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST'));
Note: a lot of the data is zero in the A-rows column because we only show last executed cursor which is the QC. Need to use ALLSTATS ALL to see info on all parallel server cursors

31

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

GATHER_PLAN_STATISTICS Hint
SELECT * FROM table ( DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS ALL'));

32

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Alternatively using MONITOR hint

33

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Most helpful hints to know


OPT_PARAM hint
Allows value for init.ora Optimizer parameters to be changed for a specific

query
Useful way to prevent setting non-default parameter value system-wide Only the following Optimizer influencing init.ora parameters can be set:

OPTIMIZER_DYNAMIC_SAMPLING
OPTIMIZER_INDEX_CACHING OPTIMIZER_INDEX_COST_ADJ OPTIMIZER_USE_PENDING_STATISTICS Optimizer related underscore parameters

STAR_TRANSFORMATION_ENABLED
PARALLEL_DEGREE_POLICY PARALLEL_DEGREE_LIMIT

34

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

OPT_PARAM hint
Example

35

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

OPT_PARAM hint
Example

36

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Most useful hints to know


OPTIMIZER_FEATURES_ENABLE hint
OPTIMIZER_FEATURES_ENABLE parameter allows you to switch

between optimizer versions Setting it to previous database version reverts the Optimizer to that version
Disables any functionality that was not present in that version

Easy way to work around unexpected behavior in a new release Hint allows you to revert the Optimizer for just a single statement

37

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Precision matters (a)


select /*+ parallel(pt1,2) */ {list of columns} from pt1 where pt1.n1 = 5 and pt1.n2 = 10 and pt1.pt_group in (0,10) ;

The optimizer DID obey the hint

. |Id|Operation |Name |Cost |Pstart| Pstop| | 0|SELECT STATEMENT | | 48| | | | 1| PARTITION LIST INLIST | | 48|KEY(I)|KEY(I)| |*2| TABLE ACCESS BY LOCAL INDEX ROWID|PT1 | 48|KEY(I)|KEY(I)| |*3| INDEX RANGE SCAN |PT1_I1| 3|KEY(I)|KEY(I)|

38

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Precision matters (b)


...

NESTED LOOP
TABLE ACCESS (FULL) OF T7 TABLE ACCESS BY INDEX ROWID T8 INDEX RANGE SCAN T8_IND_SECOND -- wrong index

... select /*+ index(t8 t8_ind_first) */


... HASH JOIN TABLE ACCESS (FULL) OF T7 TABLE ACCESS BY INDEX ROWID T8 INDEX FULL SCAN T8_IND_FIRST ...

-- hint the right one -- wrong method

-- right index

39

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

How much don't we know ?


select /*+ leading(t4 t1 t2 t3) full(t4) use_hash(t1) full(t1) use_hash(t2) full(t2) use_hash(t3) full(t3) */ ... From t4, t1, t2, t3 Where t1.id = t4.id1 and t2.id = t4.id2 and t3.id = t4.id3;

40

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

How much don't we know ?


N 1 simultaneous build (hash) tables HASH JOIN TABLE ACCESS (FULL) OF TABLE_3 HASH JOIN TABLE ACCESS (FULL) OF TABLE_2 HASH JOIN TABLE ACCESS (FULL) OF TABLE_1 TABLE ACCESS (FULL) OF TABLE_4

Maximum two simultaneous build (hash) tables


HASH JOIN HASH JOIN HASH JOIN TABLE ACCESS (FULL) OF TABLE_4 TABLE ACCESS (FULL) OF TABLE_1 TABLE ACCESS (FULL) OF TABLE_2 TABLE ACCESS (FULL) OF TABLE_3
41 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Summary
Forgive the Optimizer its not out to get you
Its knowledge is limited to the information you provide it

A complete representative set of statistics gets the best plans


Determine or have Oracle determine what extended statistics are needed

Be mindful of when you capture a representative set of statistics


Dont be afraid to adjust maintenance window or include statistics in ETL

Optimizer hints should only be used with extreme caution


To guarantee the same plan every time use SQL Plan Baselines

Enjoy the challenge!


42 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

More Information
White papers
Optimizer with Oracle Database 12c SQL Plan Management with Oracle Database 12c Understanding Optimizer Statistics with Oracle Database 12c

Blogs
http://jonathanlewis.wordpress.com/all-postings/ http://blogs.oracle.com/optimizer

Oracle.com
http://www.oracle.com/technetwork/database/focus-areas/bi-

datawarehousing/dbbi-tech-info-optmztn-092214.html
43 Copyright 2013, Oracle and/or its affiliates. All rights reserved.

44

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Vous aimerez peut-être aussi