Вы находитесь на странице: 1из 55

1

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

Oracle Optimizer: Top Tips For Preventing Suboptimal Execution plans


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

What to expect
Explanation of common mistakes that cause sub-optimal execution plans and how to avoid them The assumption is that all statistics are accurate and the cause of the sub-optimal plan lies elsewhere

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

What is assumed of you


A very basic understand of an execution plan A common definition of an access predicate
Where clause component used for data retrieval
The start and stop keys for an index If rowids are passed to a table scan

A common definition of a filter predicate


Where clause component that is not used for data retrieval but to eliminate uninteresting row once the data is found

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

Agenda
Using the right tools Functions, friends or foes? Data type dilemmas ANSI versus Oracle syntax Influencing the execution plan without adding hints

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

Using the right tools


Expected index range scan but got full table scan? Query How many customers do we have in a specific zipcode
SELECT count(cust_first_name) FROM customers2 WHERE zipcode = :n;

Customers2 table has b-tree index on zipcode There is a histogram on the zipcode column due to data skew

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

Using the right tools


Expected index range scan but got full table scan?
Set bind variable :n to 94065

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

Using the right tools


Expected index range scan but got full table scan?
Using literal value gets the expected plan

Why is the bind variable version getting the wrong plan?


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

Using the right tools


Expected index range scan but got full table scan?
Why is simple equality predicate being applied as filter and no as access?

Why is there a TO_NUMBER function on the bind variable n after it was defined as a number?

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

Using the right tools


Expected index range scan but got full table scan?
Bad plan is actually caused by using autotrace Autotrace is not aware of bind at all
Hence TO_NUMBER on n No bind peeking takes place

Cardinality estimate doesnt use histogram it is calculated using


ROW_NUM NDV 20,000 2

NOTE cursor generated by autotrace will be shared by other sessions


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

Using the right tools


Solution use DBMS_XPLAN.DISPLAY_CURSOR
Execute the statement with the bind then run DBMS_XPLAN command

11

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

Using the right tools


Solution use DBMS_XPLAN.DISPLAY_CURSOR
Can add additional parameters to display the bind variable values along with the plan

12

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

Agenda

Data type dilemmas ANSI versus Oracle syntax Influencing the execution plan without adding hints

13

Copyright 2011, 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 /*+ gather_plan_statistics */ count(*) FROM sales2 WHERE to_char(prod_id)=139;

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

14

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

Functions friends or foe?


Expected index range scan but got fast full index scan
Use hint to capture execution statistics Use format parameter of DBMS_XPLAN to show estimated and execution statistics in plan Additional column added to the plan to show Actual Rows produce by each operation

15

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

Functions friends or foe?


Expected index range scan but got fast full index scan

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
16 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Expected index range scan but got fast full index scan 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
17 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Solution - Use inverse function on other side of predicate Query rewrite
SELECT /*+ gather_plan_statistics */ count(*) FROM sales2 WHERE prod_id=to_number(139);

18

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

Functions friends or foe?


Expected query to access only 4 partitions but its accesses all

Query calculate total amount sold for one year


SELECT sum(amount_sold) FROM sh.sales s, sh.times t WHERE s.time_id = t.time_id AND TO_CHAR(s.time_id,YYYYMMDD) between 19990101 and 20000101;

Sales table is partitioned on the time_id column Sales table has quarterly partitions for historical data
19 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Functions friends or foe?


Expected query to access only 4 partitions but its accesses all
Why has an additional INTERNAL_FUNCTION been added to our predicate?

20

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

Functions friends or foe?


Expected query to access only 4 partitions but its accesses all

INTERNAL_FUNCTION typically means a data type conversion has occurred Predicate is TO_CHAR(s.time_id,YYYYMMDD) Optimizer has no idea how function will effect the values in the time_id column Optimizer cant determine which partitions will be accessed now

21

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

Functions friends or foe?


Solution Use inverse function on other side of predicate

Only 4 partitions accessed

22

Copyright 2011, 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 using a function 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 Should be AND a = c rewritten as WHERE a = inv_f(b) This will allow transitive predicate c=inv_f(b) to be AND a=c added by the optimizer

23

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

Agenda
Using the right tools Functions, friends or foes? Data type dilemmas ANSI versus Oracle syntax Influencing the execution plan without adding hints

24

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

Data type dilemmas


Expected index range scan but got fast full index scan Query Simple IAS part of an ETL process
INSERT /*+ APPEND gather_plan_statistics */ INTO t1 FROM (row_id, modification_num, operation, last_upd) t2 SELECT row_id, 1 , 'I', last_upd WHERE t2.last_upd > systimestamp;

T2 has a b-tree index on the last_upd column


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

Data type dilemmas


Expected index range scan but got fast full index scan
Only one non-equality access predicate

So why is our access predicate applied as a filter? What does INTERNAL_FUNCTION mean?

26

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

Data type dilemmas


Expected index range scan but got fast full index scan INTERNAL_FUNCTION typically means a data type conversion has occurred Predicate is t2.last_upd > systimestamp What data type is the last_upd column

27

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

Data type dilemmas


Why is the cardinality estimate wrong? Presence of the INTERNAL_FUNCTION cause the Optimizer to guess the cardinality estimate
Optimizer has no way of knowing how function effects data in LAST_UPD column Without a function based index or extended statistics the Optimizer has to guess Guess is 5% of the rows in the table

5% of 823296 is 41,164.8 or 41,165


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

Data type dilemmas


Solution correct data type mismatch Changing the predicate from SYSTIMESTAMP to SYSDATE
INSERT /*+ APPEND gather_plan_statistics */ INTO t1 (row_id, modification_num, operation, last_upd) SELECT row_id, 1 , 'I', last_upd FROM t2 WHERE t2.last_upd > sysdate;
;

29

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

Data type dilemmas


Expected to get partition pruning via a join but didnt

Query calculate total amount sold that was return same day

SELECT sum(amount_sold) FROM sh.sales s, sh.sales_returns sr WHERE s.time_id = sr.time_id AND sr.time_id=31-DEC-01;

Sales table is range partitioned on time_id Sales table has 7 years of data in quarterly partitions
30 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Data type dilemmas


Expected to get partition pruning via a join but didnt

Getting transitive predicate but Internal_function on partitioned column prevents pruning Function needed because the join columns have different data types
31 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Data type dilemmas


Solution ensure join columns have the same data type

KEY means dynamic pruning at execution time AP means And Pruning, caused by bloom filter Now get transitive predicate without data type conversion hence pruning
32 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Agenda
Using the right tools Functions, friends or foes? Data type dilemmas ANSI versus Oracle syntax Influencing the execution plan without adding hints

33

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

ANSI versus Oracle Syntax


Expected Nest Loop Outer Join but got Sort Merge Join While migrating an application to Oracle the following ANSI SQL was translated into Oracle syntax
SELECT d.dname, e.empno FROM dept d LEFT OUTER JOIN emp e ON (d.deptno = e.deptno AND (d.loc = 'NEW YORK' or e.ename like 'S%') ); SELECT d.dname, e.empno FROM dept d, emp e WHERE d.deptno = e.deptno (+) AND (d.loc = 'NEW YORK' or e.ename like 'S%');

34

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

ANSI versus Oracle Syntax


Expected Nest Loop Outer Join but got Sort Merge Join ANSI Syntax
SELECT d.dname, e.empno FROM dept d LEFT OUTER JOIN emp e ON (d.deptno = e.deptno AND (d.loc = 'NEW YORK' or e.ename like 'S%'));

35

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

ANSI versus Oracle Syntax


Expected Nest Loop Outer Join but got Sort Merge Join Oracle Syntax
SELECT d.dname, e.empno FROM dept d, emp e WHERE d.deptno = e.deptno (+) AND (d.loc = 'NEW YORK' or e.ename like 'S%');

Why does the predicate section of the Oracle Syntax plan look so different from the Ansi SQL version?

36

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

ANSI versus Oracle Syntax


Oracle syntax didnt return the same results as ANSI
ANSI syntax returns7 rows Oracle syntax returns only 5 rows

37

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

ANSI versus Oracle Syntax


Expected Nest Loop Outer Join but got Sort Merge Join Oracle Syntax is not equivalent to Ansi SQL In Ansi SQL filter predicates are evaluated before join Predicates are evaluated by creating a lateral view on View definition would be EMP

SELECT e.empno FROM emp e WHERE (d.loc = 'NEW YORK' or e.ename like 'S%') AND d.deptno = e.deptno;

38

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

ANSI versus Oracle Syntax


Expected Nest Loop Outer Join but got Sort Merge Join Correct Oracle translation of the Ansi SQL
SELECT d.dname, v.empno FROM dept d, lateral(SELECT e.empno FROM emp e WHERE (d.loc = 'NEW YORK' or e.ename like 'S%') AND d.deptno = e.deptno)(+) v;

In Oracle Database11g lateral keyword only active if events 22829 is set


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

ANSI versus Oracle Syntax


Expected Nest Loop Outer Join but got Sort Merge Join Complete Oracle translation of the Ansi SQL
Alter session set events '22829 trace name context forever, level 1'; SELECT d.dname, v.empno FROM dept d, lateral(SELECT e.empno FROM emp e WHERE (d.loc = 'NEW YORK' or e.ename like 'S%') AND d.deptno = e.deptno)(+) v;

40

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

Agenda
Using the right tools Functions, friends or foes? Data type dilemmas ANSI versus Oracle syntax Influencing the execution plan without adding hints

41

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

How to influence the execution plan without adding hints


Even if statistics are accurate and up to date you may need to influence the optimizer with a hint Most third party application dont provide a mechanism to add hints to generate SQL Solution is to use SQL Plan Management (SPM) SPM available in EE, no additional options required

42

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

How to influence the execution plan without adding hints


1. In a SQL*Plus session run the non-hinted SQL statement to begin the SQL plan baseline capture

43

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

How to influence the execution plan without adding hints


2. Find the SQL_ID for the non-hinted statement in V$SQL

44

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

How to influence the execution plan without adding hints


3. Create a SQL plan baseline for the non-hinted SQL statement

45

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

How to influence the execution plan without adding hints


4. The plan that was captured is not our desired plan so it should be disabled using DBMS_SPM.ALTER_SQL_PLAN_BASELINE

46

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

How to influence the execution plan without adding hints


5. Modify the SQL statement to use the hint(s) & execute it

47

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

How to influence the execution plan without adding hints


6. Find new SQL_ID and PLAN_HASH_VALUE for the hinted SQL stmt in V$SQL

48

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

How to influence the execution plan without adding hints


7. Associate hinted plan with original SQL statements SQL HANDLE

Sql_id & plan_hash_value belong to hinted statement

sql_handle is for the non-hinted statement

49

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

How to influence the execution plan without adding hints


8. In DBA_SQL_PLAN_BASELINE we nowhave two plans for this stmt, one enabled and one disables

Hinted plan only accepted plan for non-hinted SQL stmt


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

Confirm that non-hinted SQL statement will now use hinted


Non-hinted SQL text but it is using the plan hash value for the hinted stmt Note section also confirms SQL plan baseline used for stmt

51

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

Summary
Choose your plan displaying tool wisely
They dont all show the correct plan and can effect other sessions

Place functions carefully


Avoid adding them to table columns as it can limit access paths

Data types
If INTERNAL_FUNCTION appears in the predicate section check data types used in where clause predicates and across joins

Translate ANSI SQL with caution


Some times it better to leave it as ANSI SQL
52 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Q&A

53

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

Oracle Optimizer Schedule for Oracle Open World!


Date Title Loca,on Speaker

Monday Oct 3rd 12:30 PM"

Oracle Optimizer: Prevent Suboptimal " Execution Plans" " Hands-on-Lab! Oracle Optimizer: Best Practices for Managing Optimizer Statistics"

Marriott Marquis - Salon 12/13"

Maria Colgan"
Senior Principal Member of Technical Staff" Oracle"

Wednesday Oct 5th 10:15 AM "

Moscone South - 103"

Maria Colgan"
Senior Principal Member of Technical Staff" Oracle"

Thursday Oct 6th 12:00 PM"

Oracle Database Optimizer: Tips for " Preventing Suboptimal Execution Plans"

Moscone South - 104"

Maria Colgan"
Senior Principal Member of Technical Staff" Oracle"

Mohamed Zait"
Architect" Oracle"

54

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

55

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

Вам также может понравиться