SlideShare a Scribd company logo
1 of 76
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Understanding Query Optimization
with ‘regular’ and ‘Exadata’ Oracle
Thomas Kyte
http://asktom.oracle.com/
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Statement Processing and the Optimizer
What Happens when a SQL statement is issued?
User
Library Cache
Shared SQL Area
Shared Pool
CnC1 C2 …
3
Cost Estimator
Query Transformation
Plan Generator
Optimizer
Oracle Database
1
Syntax Check
Semantic Check
Shared Pool check
2
Parsing
4
SQL Execution
Code Generator Decision on what processing is
offloaded occurs here
<Insert Picture Here>
What is an execution
plan and how to
generate one
What is an Execution plan?
• Execution plans show the detailed steps necessary to
execute a SQL statement
• These steps are expressed as a set of database
operators that consumes and produces rows
• The order of the operators and their implementation is
decided by the optimizer using a combination of query
transformations and physical optimization techniques
• The display is commonly shown in a tabular format,
but a plan is in fact tree-shaped
Group By
HASH JOIN
TABLE ACCESS
SALES
TABLE ACCESS
PRODUCTS
What is an Execution plan?
Query
SELECT prod_category, avg(amount_sold)
FROM sales s, products p
WHERE p.prod_id = s.prod_id
GROUP BY prod_category;
Tabular representation of plan
-----------------------------------------
Id Operation Name
-----------------------------------------
0 SELECT STATEMENT
1 HASH GROUP BY
2 HASH JOIN
3 TABLE ACCESS FULL PRODUCTS
4 PARTITION RANGE ALL
5 TABLE ACCESS FULL SALES
-----------------------------------------
Tree-shaped representation of plan
How to get an Execution Plan
Two methods for looking at the execution plan
1.EXPLAIN PLAN command
• Displays an execution plan for a SQL statement without actually
executing the statement
2.V$SQL_PLAN
• A dictionary view introduced in Oracle 9i that shows the execution
plan for a SQL statement that has been compiled into a cursor in
the cursor cache
Use DBMS_XPLAN package to display plans
Under certain conditions the plan shown with EXPLAIN PLAN
can be different from the plan shown using V$SQL_PLAN
How to get an Execution Plan
Example 1 EXPLAIN PLAN command & dbms_xplan.display function
SQL> EXPLAIN PLAN FOR SELECT prod_category, avg(amount_sold)
FROM sales s, products p
WHERE p.prod_id = s.prod_id
GROUP BY prod_category;
Explained
SQL> SELECT plan_table_output
FROM table(dbms_xplan.display('plan_table',null,'basic'));
------------------------------------------
Id Operation Name
------------------------------------------
0 SELECT STATEMENT
1 HASH GROUP BY
2 HASH JOIN
3 TABLE ACCESS FULL PRODUCTS
4 PARTITION RANGE ALL
5 TABLE ACCESS FULL SALES
-------------------------------------------
Explain Plan “lies”
• Explain plan should hardly ever be used…
• You have to be careful when using autotrace and
related tools
• Never use “explain=u/p” with tkprof
• Avoid dbms_xplan.display, use display_cursor
Explain plan lies…
ops$tkyte%ORA11GR2> create table t
2 as
3 select 99 id, to_char(object_id) str_id, a.*
4 from all_objects a
5 where rownum <= 20000;
Table created.
ops$tkyte%ORA11GR2> update t
2 set id = 1
3 where rownum = 1;
1 row updated.
ops$tkyte%ORA11GR2> create index t_idx on t(id);
Index created.
ops$tkyte%ORA11GR2> create index t_idx2 on t(str_id);
Index created.
Explain plan lies…
ops$tkyte%ORA11GR2> begin
2 dbms_stats.gather_table_stats
3 ( user, 'T',
4 method_opt=>'for all indexed columns size 254',
5 estimate_percent => 100,
6 cascade=>TRUE );
7 end;
8 /
PL/SQL procedure successfully completed.
Explain plan lies…
Need a volunteer
Explain plan lies…
Need a volunteer
select count(*) from t where id = :n;
What cardinality would you estimate
and why?
Explain plan lies…
ops$tkyte%ORA11GR2> variable n number
ops$tkyte%ORA11GR2> exec :n := 1;
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> set autotrace on explain
ops$tkyte%ORA11GR2> select count(subobject_name) from t where id = :n;
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 20 | 86 (0)| 00:00:02 |
| 1 | SORT AGGREGATE | | 1 | 20 | | |
|* 2 | TABLE ACCESS FULL| T | 10000 | 195K| 86 (0)| 00:00:02 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("ID"=TO_NUMBER(:N)) <<<<===== to_number?
Explain plan lies…
ops$tkyte%ORA11GR2> select * from
table(dbms_xplan.display_cursor('98mx7jbn7jpm8', '', '+peeked_binds'));
select count(subobject_name) from t where id = :n
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | SORT AGGREGATE | | 1 | 20 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 1 | 20 | 2 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
1 - :N (NUMBER): 1
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("ID"=:N)
Explain plan lies…
ops$tkyte%ORA11GR2> set autotrace traceonly explain
ops$tkyte%ORA11GR2> select object_id from t where str_id = :n;
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 19 | 2 (0)| 00:0
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 19 | 2 (0)| 00:0
|* 2 | INDEX RANGE SCAN | T_IDX2 | 1 | | 1 (0)| 00:0
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("STR_ID"=:N) <<== interesting…
Explain plan lies…
ops$tkyte%ORA11GR2> select object_id from t where str_id = :n;
OBJECT_ID
----------
99
ops$tkyte%ORA11GR2> select * from table(dbms_xplan.display_cursor);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 86 (100)| |
|* 1 | TABLE ACCESS FULL| T | 1 | 19 | 86 (0)| 00:00:02 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("STR_ID")=:N) <<= string has to convert..
Explain plan lies…
1 - filter(TO_NUMBER("STR_ID")=:N) <<= string has to convert..
STR_ID
------
0
00
000
0.00
+0
-0
1,000
1.000
How to get an Execution Plan
Example 2 Generate & display execution plan for the last SQL stmts
executed in a session
SQL>SELECT prod_category, avg(amount_sold)
FROM sales s, products p
WHERE p.prod_id = s.prod_id
GROUP BY prod_category;
no rows selected
SQL> SELECT plan_table_output
FROM table(dbms_xplan.display_cursor(null,null,'basic'));
------------------------------------------
Id Operation Name
------------------------------------------
0 SELECT STATEMENT
1 HASH GROUP BY
2 HASH JOIN
3 TABLE ACCESS FULL PRODUCTS
4 PARTITION RANGE ALL
5 TABLE ACCESS FULL SALES
-------------------------------------------
How to get an Execution Plan
Example 3 Displaying execution plan for any other statement from
V$SQL_PLAN
1.Directly:
SQL> SELECT plan_table_output FROM
table(dbms_xplan.display_cursor('fnrtqw9c233tt',null,'basic'));
2.Indirectly:
SQL> SELECT plan_table_output
FROM v$sql s,
TABLE(dbms_xplan.display_cursor(s.sql_id,s.child_number, 'basic')) t
WHERE s.sql_text like 'select PROD_CATEGORY%';
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• So what operations can actually be offloaded?
– Full table scan
– Fast full index scan of a B-Tree or bitmap index
– Bloom filters
• But not all predicates can be offloaded
– V$SQLFN_METADATA has a column called offloadable
– Indicates if SQL function is offloadable or not
– With each new release more function can be offloaded
– For example TRUNC is but RANK is not offloadable
History
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• The plan always shows an eligible operation is offloaded
History
The display of the word STORAGE is
actually controlled by the parameter
cell_offload_plan_display it is not an
indication that offloading will or has
occurred, just that it is possible
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• The plan always shows an eligible operation is offloaded
History
The word STORAGE in the predicate
information is controlled by another
internal optimizer parameter
<Insert Picture Here>
What is a good plan
for the optimizer
What’s a Good Plan for the Optimizer?
The Optimizer has two different goals
• Serial execution: It’s all about cost
• The cheaper, the better
• Parallel execution: it’s all about performance
• The faster, the better
Two fundamental questions:
• What is cost?
• What is performance?
What is Cost?
• A magically number the optimizer makes up?
• Resources required to execute a SQL statement?
• Result of complex calculations?
• Estimate of how long it will take to execute a statement?
Actual Definition
• Cost represents units of work or resources used
• Optimizer uses CPU & memory usage plus IO as units of work
• Cost is an estimate of the amount of CPU and memory plus the number of
disk I/Os, used in performing an operation
Cost is an internal Oracle measurement
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> create table organized
2 as
3 select x.*
4 from (select * from stage order by object_name) x
5 /
Table created.
ops$tkyte%ORA11GR2> create table disorganized
2 as
3 select x.*
4 from (select * from stage order by dbms_random.random) x
5 /
Table created.
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> create index organized_idx on
organized(object_name);
Index created.
ops$tkyte%ORA11GR2> create index disorganized_idx on
disorganized(object_name);
Index created.
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> begin
2 dbms_stats.gather_table_stats
3 ( user, 'ORGANIZED',
4 estimate_percent => 100,
5 method_opt=>'for all indexed columns size 254'
6 );
7 dbms_stats.gather_table_stats
8 ( user, 'DISORGANIZED',
9 estimate_percent => 100,
10 method_opt=>'for all indexed columns size 254'
11 );
12 end;
13 /
PL/SQL procedure successfully completed.
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> select table_name, blocks, num_rows, 0.05*num_rows,
0.10*num_rows from user_tables
2 where table_name like '%ORGANIZED' order by 1;
TABLE_NAME BLOCKS NUM_ROWS 0.05*NUM_ROWS 0.10*NUM_ROWS
------------------------------ ---------- ---------- ------------- -------------
DISORGANIZED 1062 72774 3638.7 7277.4
ORGANIZED 1062 72774 3638.7 7277.4
ops$tkyte%ORA11GR2> select table_name, index_name, clustering_factor
from user_indexes
2 where table_name like '%ORGANIZED' order by 1;
TABLE_NAME INDEX_NAME CLUSTERING_FACTOR
------------------------------ ------------------------------ -----------------
DISORGANIZED DISORGANIZED_IDX 72727
ORGANIZED ORGANIZED_IDX 1036
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> select /*+ index( organized organized_idx) */
2 count(subobject_name)
3 from organized;
COUNT(SUBOBJECT_NAME)
---------------------
542
ops$tkyte%ORA11GR2> select /*+ index( disorganized disorganized_idx) */
2 count(subobject_name)
3 from disorganized;
COUNT(SUBOBJECT_NAME)
---------------------
542
Clustering Factor and Cost Example
select /*+ index( organized organized_idx) */
count(subobject_name)
from organized
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.45 0.45 1036 1398 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.45 0.46 1036 1398 0 1
Row Source Operation
---------------------------------------------------
SORT AGGREGATE (cr=1398 pr=1036 pw=0 time=456653 us)
TABLE ACCESS BY INDEX ROWID ORGANIZED (cr=1398 pr=1036 pw=0 time=376835 us cos…
INDEX FULL SCAN ORGANIZED_IDX (cr=362 pr=0 pw=0 time=98362 us cost=363 …
1,398-362 = 1,036 - the Clustering Factor and Cost Example…
Clustering Factor and Cost Example
select /*+ index( disorganized disorganized_idx) */
count(subobject_name)
from disorganized
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.83 0.83 1036 73089 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.83 0.83 1036 73089 0 1
Row Source Operation
---------------------------------------------------
SORT AGGREGATE (cr=73089 pr=1036 pw=0 time=835554 us)
TABLE ACCESS BY INDEX ROWID DISORGANIZED (cr=73089 pr=1036 pw=0 time=750651 us …
INDEX FULL SCAN DISORGANIZED_IDX (cr=362 pr=0 pw=0 time=96421 us cost=363 …
73,089-362 = 72,727 - the Clustering Factor and Cost Example…
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> select * from organized where object_name like 'F%';
Execution Plan
----------------------------------------------------------
Plan hash value: 1925627673
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CP
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 149 | 14453 | 6 (
| 1 | TABLE ACCESS BY INDEX ROWID| ORGANIZED | 149 | 14453 | 6 (
|* 2 | INDEX RANGE SCAN | ORGANIZED_IDX | 149 | | 3 (
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_NAME" LIKE 'F%')
filter("OBJECT_NAME" LIKE 'F%')
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> select * from disorganized where object_name like 'F%';
Execution Plan
----------------------------------------------------------
Plan hash value: 3767053355
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 149 | 14453 | 152
| 1 | TABLE ACCESS BY INDEX ROWID| DISORGANIZED | 149 | 14453 | 152
|* 2 | INDEX RANGE SCAN | DISORGANIZED_IDX | 149 | | 3
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_NAME" LIKE 'F%')
filter("OBJECT_NAME" LIKE 'F%')
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> select * from organized where object_name like 'A%';
Execution Plan
----------------------------------------------------------
Plan hash value: 1925627673
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CP
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1824 | 172K| 38 (
| 1 | TABLE ACCESS BY INDEX ROWID| ORGANIZED | 1824 | 172K| 38 (
|* 2 | INDEX RANGE SCAN | ORGANIZED_IDX | 1824 | | 12 (
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_NAME" LIKE 'A%')
filter("OBJECT_NAME" LIKE 'A%')
Clustering Factor and Cost Example
ops$tkyte%ORA11GR2> select * from disorganized where object_name like 'A%';
Execution Plan
----------------------------------------------------------
Plan hash value: 2727546897
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1824 | 172K| 290 (1)| 00:00:0
|* 1 | TABLE ACCESS FULL| DISORGANIZED | 1824 | 172K| 290 (1)| 00:00:0
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME" LIKE 'A%')
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
‘Regular’ and Exadata plans and the Optimizer
Overview
Optimizer selects the
wrong plan because
Incorrect
cardinality
estimate
Not accounting
correctly for
speed of scans
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Overview
Optimizer selects the
wrong plan because
Incorrect
cardinality
estimate
Not accounting
correctly for
speed of scans
<Insert Picture Here>
Understanding an
Execution Plan
SQL Execution Plan
When looking at a plan can you determine if the following is correct?
• Cardinality
• Are the correct number of rows coming out of each object?
• Access paths
• Is the data being accessed in the best way? Scan? Index lookup?
• Join order
• Are tables being joined in the correct order to eliminate as much data as early as possible?
• Join type
• Are the right join types being used?
• Partitioning pruning
• Did I get partition pruning? Is it eliminating enough data?
• Parallelism
Cardinality
What is it?
• Estimate of number rows that will be returned
• Cardinality for a single value predicate = num_rows total / num_distinct total
• E.g. 100 rows total, 10 distinct values => cardinality=10 rows
• OR if histogram present num_rows * Density
Why should you care?
• Influences everything! Access method, Join type, Join Order etc
What causes Cardinality to be wrong?
• Stale or no statistics
• Data Skews
• Multiple single column predicates on a table
• A function wrapped where clause predicate
• Complicated expressions that contain columns from different tables
“Wrong Plan =>
Wrong Cardinality”
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> create table t
2 as select decode( mod(rownum,2), 0, 'N', 'Y' ) flag1,
3 decode( mod(rownum,2), 0, 'Y', 'N' ) flag2, a.*
4 from all_objects a
5 /
Table created.
ops$tkyte%ORA11GR2> create index t_idx on t(flag1,flag2);
Index created.
ops$tkyte%ORA11GR2> begin
2 dbms_stats.gather_table_stats
3 ( user, 'T',
4 method_opt=>'for all indexed columns size 254' );
5 end;
6 /
PL/SQL procedure successfully completed.
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> select 'select * from t', num_rows
2 from user_tables where table_name = 'T'
3 union all
4 select 'select * from t where flag1 = "N"', num_rows/2
5 from user_tables where table_name = 'T'
6 union all
7 select 'select * from t where flag2 = "N"', num_rows/2
8 from user_tables where table_name = 'T'
9 union all
10 select 'select * from t where flag1 = "N" and flag2 = "N"', num_rows/2/2
11 from user_tables where table_name = 'T';
'SELECT*FROMT' NUM_ROWS
------------------------------------------------- ----------
select * from t 72726
select * from t where flag1 = "N" 36363
select * from t where flag2 = "N" 36363
select * from t where flag1 = "N" and flag2 = "N" 18181.5
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> set autotrace traceonly explain
ops$tkyte%ORA11GR2> select * from t where flag1='N';
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 36499 | 3635K| 301 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T | 36499 | 3635K| 301 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("FLAG1"='N')
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> select * from t where flag2='N';
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 36227 | 3608K| 301 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T | 36227 | 3608K| 301 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("FLAG2"='N')
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> select * from t where flag1='N' and flag2='N';
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 18181 | 1810K| 301 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T | 18181 | 1810K| 301 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("FLAG2"='N' AND "FLAG1"='N')
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> select /*+ gather_plan_statistics */ *
2 from t where flag1='N' and flag2='N';
no rows selected
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.02 | 1080 |
|* 1 | TABLE ACCESS FULL| T | 1 | 18181 | 0 |00:00:00.02 | 1080 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(("FLAG2"='N' AND "FLAG1"='N'))
19 rows selected.
Wrong Plan => Wrong Cardinality
ops$tkyte%ORA11GR2> select /*+ dynamic_sampling(t 3) */ * from t where flag1='N' and flag2='N';
Execution Plan
----------------------------------------------------------
Plan hash value: 470836197
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 612 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 6 | 612 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 6 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("FLAG1"='N' AND "FLAG2"='N')
Note
-----
- dynamic sampling used for this statement (level=2)
Wrong Plan => Wrong Cardinality
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */
NVL(SUM(C1),:"SYS_B_00"), NVL(SUM(C2),:"SYS_B_01"), NVL(SUM(C3),:"SYS_B_02")
FROM
(SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("T") FULL("T")
NO_PARALLEL_INDEX("T") */
:"SYS_B_03" AS C1,
CASE WHEN "T"."FLAG1"= :"SYS_B_04" AND "T"."FLAG2"=:"SYS_B_05"
THEN :"SYS_B_06"
ELSE :"SYS_B_07"
END AS C2,
CASE WHEN "T"."FLAG2"=:"SYS_B_08" AND "T"."FLAG1"=:"SYS_B_09“
THEN :"SYS_B_10"
ELSE :"SYS_B_11"
END AS C3
FROM "OPS$TKYTE"."T"
SAMPLE BLOCK (:"SYS_B_12" , :"SYS_B_13") SEED (:"SYS_B_14") "T") SAMPLESUB
Check Cardinality using
SELECT /*+ gather_plan_statistics */
p.prod_name as product, sum(s.quantity_sold) as units,
FROM sales s, products p
WHERE s.prod_id =p.prod_id
GROUP BY p.prod_name;
SELECT * FROM table (
DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST'));
compare the estimated number of rows returned for each operation in the plan to actual rows returned
Check Cardinality using SQL Monitor
SQL Monitor allows you to compare the
estimated number of rows returned for each
operation in the plan to actual rows returned
Suggestions for fixing Cardinality issues
Cause Solution
Stale or no statistics DBMS_STATS
Data Skew Create a histogram*
Multiple single column predicates on a
table
Create a column group using
DBMS_STATS.CREATE_EXTENDED_STATS
Multiple columns used in a join Create a column group using
DBMS_STATS.CREATE_EXTENDED_STATS
Function wrapped column Create statistics on the function wrapped column using
DBMS_STATS.CREATE_EXTENDED_STATS
Complicated expression containing
columns from multiple tables
Use dynamic sampling level 4 or higher
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Why the Optimizer picks the wrong
plan broken down by the percentage
Incorrect cardinality
estimate
Not accounting
correctly for speed of
scans
Not accounting for
HCC decompression
• More than 85% of the plan
problems reported on Exadata
are caused by Incorrect
cardinality estimates
• Fix cardinality estimates
before trying any other tuning
techniques
• Typically fixing the cardinality
estimates achieves the
desired plan
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Overview
Optimizer selects the
wrong plan because
Incorrect
cardinality
estimate
Not accounting
correctly for
speed of scans
Complex
Expressions
Incomplete
stats
Stale
Stats
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Non-Exadata System: Indexes vs. FTS
Not accounting for speed of scans
• On a non-Exadata system the
cost of a full table scan far out
weighs the cost of an index
range scan or even a fast full
index scan
Rows
Full Table Scan
Index Scan
Cost
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Non-Exadata System: Indexes vs. FTS
Not accounting for speed of scans
• On a non-Exadata system the
cost of a full table scan far out
weighs the cost of an index
range scan or even a fast full
index scan
• Typically the elapse times
follows suit
Rows
Full Table Scan
Index Scan
Time
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Exadata System: Indexes vs. FTS
Not accounting for speed of scans
Rows
Full Table Scan
Index Scan
• On an Exadata system the
cost of the full table scan still
exceeds the cost of an index
scan
CostTime
• BUT in reality the elapse time
can often be much faster
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• TEST_TBL table contains 20 million rows
– 22 Columns consisting of numbers and string data types
• Compressed using HCC query high
• Index created on UK column
– This is a unique index
– Values range from 1 to 20 million
Not accounting correctly for the speed of scan
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Query: Create table <name> as
Select * from test_tbl t where UK <= :VAL;
Default plan is index range scan
Elapse time is 13.33 seconds
Not accounting for speed of scans
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Query: Create table <name>as
Select /*+ full(t) */ * from test_tbl t where UK <= :VAL;
Forced plan is full table scan
Elapse time is 5.8 seconds
Not accounting for speed of scans
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• So the answer is simple
• Drop all of the indexes
• Everything will be faster via a full table scan
Not accounting for speed of scans
• Not so fast
• What happens when you have multiple concurrent users?
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Non-Exadata
Exadata
Exadata and the Optimizer
Performance of concurrent Full Table scan
Not accounting for speed of scans
# of concurrent scans
• With Exadata the number of
concurrent scan operations
that can be sustained before
the elapse time gets too high
is greater due to offload
• Predicate push-down
• Column projection
• But at some point it stops
scaling
• Optimizer needs to be aware
of this too
Time
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• How can you influence the Optimizer to pick a full table
scan even with an index present?
Not accounting for speed of scans
• DO NOT use OPTIMIZER_INDEX_COST_ADJ
• It doesn’t influence full table scan cost
• It is a multiplier on the cost of an index access
• Setting it to 400 makes the index cost jump 4X from 2028 to 8114
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
• Better to look at statistics that influence Optimizer’s
decisions
• Cost of scan determined by Number of blocks to read
MBRC
• What is Multi Block Read Count (MBRC)?
– Number of db blocks read in a single OS read command
– On Exadata one OS read is 1MB of data or 128 8KB db blocks
Not accounting correctly for the speed of scan
But the Optimizer uses MBRC of 8 by default
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Not accounting correctly for the speed of scan
• System statistics tell the
Optimizer about the speed of
IO on a system
• By default system statistics
does not gather MBRC
• Only buffer IO are monitored
• Direct path IO are excluded
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Accounting correctly for the speed of scan
• New GATHER_SYSTEM_STATS
mode exclusively for EXADATA
• Monitors and captures MBRC
• For 8KB block size captures
128
• New method for monitoring
IOTFRSPEED
• Captures roughly 200MB per
second per process
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Default plans after
exec dbms_stats.gather_system_stats('EXADATA');
Accounting for speed of scans
Cost of full table scan is now
lower than the index range
scan of 21120
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Query: Select * from test_tbl where UK <= :VAL;
Full table scan plan with default system statistics
Full table scan plan with EXADATA system statistics
Accounting for speed of scans
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Exadata System: Indexes vs. FTS
Accounting for speed of scans
• With the correct system
statistics in place the cost for a
full table scan more accurately
reflects the expected
performance
• This will not prevent the
Optimizer from selecting an
index
• It just lowers the inflection
point where the plan will
switch from an index access to
a full table scan
Rows
Full Table Scan
Index Scan
Cost
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Overview
Optimizer selects the
wrong plan because
Incorrect
cardinality
estimate
Not accounting
correctly for
speed of scans
Complex
Expressions
Incomplete
stats
Stale
Stats
By default
Optimizer
assumes
MBRC = 8
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Exadata and the Optimizer
Overview
Optimizer selects the
wrong plan because
Incorrect
cardinality
estimate
Not accounting
correctly for
speed of scans
Complex
Expressions
Incomplete
stats
Stale
Stats
By default
Optimizer
assumes
MBRC = 8
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
More Information
• White papers
– Technical overview of the Exadata Database Machine
– What to expect from the Oracle Optimizer in 11g
• Optimizer Blog
– http://blogs.oracle.com/optimizer
• Oracle.com
– http://www.oracle.com/us/products/database/exadata/overview/in
dex.html
– http://www.oracle.com/technetwork/database/focus-areas/bi-
datawarehousing/dbbi-tech-info-optmztn-092214.html
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.
Q&A
Copyright © 2012, Oracle and/or its affiliates. All rights
reserved.

More Related Content

What's hot

Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Aaron Shilo
 
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
 Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo... Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
Enkitec
 
Understanding my database through SQL*Plus using the free tool eDB360
Understanding my database through SQL*Plus using the free tool eDB360Understanding my database through SQL*Plus using the free tool eDB360
Understanding my database through SQL*Plus using the free tool eDB360
Carlos Sierra
 
Exadata and the Oracle Optimizer: The Untold Story
Exadata and the Oracle Optimizer: The Untold StoryExadata and the Oracle Optimizer: The Untold Story
Exadata and the Oracle Optimizer: The Untold Story
Enkitec
 
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
Carlos Sierra
 

What's hot (20)

Oracle Performance Tuning Fundamentals
Oracle Performance Tuning FundamentalsOracle Performance Tuning Fundamentals
Oracle Performance Tuning Fundamentals
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
 
Tanel Poder - Scripts and Tools short
Tanel Poder - Scripts and Tools shortTanel Poder - Scripts and Tools short
Tanel Poder - Scripts and Tools short
 
Oracle Performance Tuning Fundamentals
Oracle Performance Tuning FundamentalsOracle Performance Tuning Fundamentals
Oracle Performance Tuning Fundamentals
 
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
 Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo... Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
 
Oracle statistics by example
Oracle statistics by exampleOracle statistics by example
Oracle statistics by example
 
How a Developer can Troubleshoot a SQL performing poorly on a Production DB
How a Developer can Troubleshoot a SQL performing poorly on a Production DBHow a Developer can Troubleshoot a SQL performing poorly on a Production DB
How a Developer can Troubleshoot a SQL performing poorly on a Production DB
 
Adapting and adopting spm v04
Adapting and adopting spm v04Adapting and adopting spm v04
Adapting and adopting spm v04
 
SQL Plan Directives explained
SQL Plan Directives explainedSQL Plan Directives explained
SQL Plan Directives explained
 
SQL Tuning 101
SQL Tuning 101SQL Tuning 101
SQL Tuning 101
 
Understanding my database through SQL*Plus using the free tool eDB360
Understanding my database through SQL*Plus using the free tool eDB360Understanding my database through SQL*Plus using the free tool eDB360
Understanding my database through SQL*Plus using the free tool eDB360
 
Oracle Database SQL Tuning Concept
Oracle Database SQL Tuning ConceptOracle Database SQL Tuning Concept
Oracle Database SQL Tuning Concept
 
Mastering PostgreSQL Administration
Mastering PostgreSQL AdministrationMastering PostgreSQL Administration
Mastering PostgreSQL Administration
 
DOAG Oracle Unified Audit in Multitenant Environments
DOAG Oracle Unified Audit in Multitenant EnvironmentsDOAG Oracle Unified Audit in Multitenant Environments
DOAG Oracle Unified Audit in Multitenant Environments
 
Oracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention TroubleshootingOracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention Troubleshooting
 
Exadata and the Oracle Optimizer: The Untold Story
Exadata and the Oracle Optimizer: The Untold StoryExadata and the Oracle Optimizer: The Untold Story
Exadata and the Oracle Optimizer: The Untold Story
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1
 
Understanding oracle rac internals part 2 - slides
Understanding oracle rac internals   part 2 - slidesUnderstanding oracle rac internals   part 2 - slides
Understanding oracle rac internals part 2 - slides
 
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
 
Indexing Strategies for Oracle Databases - Beyond the Create Index Statement
Indexing Strategies for Oracle Databases - Beyond the Create Index StatementIndexing Strategies for Oracle Databases - Beyond the Create Index Statement
Indexing Strategies for Oracle Databases - Beyond the Create Index Statement
 

Viewers also liked

Apache Tajo: Query Optimization Techniques and JIT-based Vectorized Engine
Apache Tajo: Query Optimization Techniques and JIT-based Vectorized EngineApache Tajo: Query Optimization Techniques and JIT-based Vectorized Engine
Apache Tajo: Query Optimization Techniques and JIT-based Vectorized Engine
DataWorks Summit
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer Overview
MYXPLAIN
 
Database , 8 Query Optimization
Database , 8 Query OptimizationDatabase , 8 Query Optimization
Database , 8 Query Optimization
Ali Usman
 

Viewers also liked (6)

Apache Tajo: Query Optimization Techniques and JIT-based Vectorized Engine
Apache Tajo: Query Optimization Techniques and JIT-based Vectorized EngineApache Tajo: Query Optimization Techniques and JIT-based Vectorized Engine
Apache Tajo: Query Optimization Techniques and JIT-based Vectorized Engine
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer Overview
 
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
 
Database , 8 Query Optimization
Database , 8 Query OptimizationDatabase , 8 Query Optimization
Database , 8 Query Optimization
 
SQL Joins and Query Optimization
SQL Joins and Query OptimizationSQL Joins and Query Optimization
SQL Joins and Query Optimization
 
Oracle Exadata - Issues and Challenges
Oracle Exadata - Issues and ChallengesOracle Exadata - Issues and Challenges
Oracle Exadata - Issues and Challenges
 

Similar to Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle

Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
j9soto
 
D73549GC10_06.pptx
D73549GC10_06.pptxD73549GC10_06.pptx
D73549GC10_06.pptx
VLQuyNhn
 
Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)
Hemant K Chitale
 

Similar to Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle (20)

Oracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor formatOracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor format
 
Do You Know The 11g Plan?
Do You Know The 11g Plan?Do You Know The 11g Plan?
Do You Know The 11g Plan?
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
 
EvolveExecutionPlans.pdf
EvolveExecutionPlans.pdfEvolveExecutionPlans.pdf
EvolveExecutionPlans.pdf
 
Managing Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query Performance
 
D73549GC10_06.pptx
D73549GC10_06.pptxD73549GC10_06.pptx
D73549GC10_06.pptx
 
Oracle 12c SPM
Oracle 12c SPMOracle 12c SPM
Oracle 12c SPM
 
Oracle 11g caracteristicas poco documentadas 3 en 1
Oracle 11g caracteristicas poco documentadas 3 en 1Oracle 11g caracteristicas poco documentadas 3 en 1
Oracle 11g caracteristicas poco documentadas 3 en 1
 
Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan Directives
 
PoC Oracle Exadata - Retour d'expérience
PoC Oracle Exadata - Retour d'expériencePoC Oracle Exadata - Retour d'expérience
PoC Oracle Exadata - Retour d'expérience
 
Adaptive Query Optimization
Adaptive Query OptimizationAdaptive Query Optimization
Adaptive Query Optimization
 
Top 10 tips for Oracle performance
Top 10 tips for Oracle performanceTop 10 tips for Oracle performance
Top 10 tips for Oracle performance
 
Sql and PL/SQL Best Practices I
Sql and PL/SQL Best Practices ISql and PL/SQL Best Practices I
Sql and PL/SQL Best Practices I
 
DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2
 
DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2
 
Oracle 122 partitioning_in_action_slide_share
Oracle 122 partitioning_in_action_slide_shareOracle 122 partitioning_in_action_slide_share
Oracle 122 partitioning_in_action_slide_share
 
Oracle Database Performance Tuning Basics
Oracle Database Performance Tuning BasicsOracle Database Performance Tuning Basics
Oracle Database Performance Tuning Basics
 
Five more things about Oracle SQL and PLSQL
Five more things about Oracle SQL and PLSQLFive more things about Oracle SQL and PLSQL
Five more things about Oracle SQL and PLSQL
 

More from Guatemala User Group

More from Guatemala User Group (20)

La transformacion digital en nuestra vida cotidiana. Un vistazo a las APIs
La transformacion digital en nuestra vida cotidiana. Un vistazo a las APIsLa transformacion digital en nuestra vida cotidiana. Un vistazo a las APIs
La transformacion digital en nuestra vida cotidiana. Un vistazo a las APIs
 
Cloud Integration for Human Resources: Connect with Your talent in the Cloud
Cloud Integration for Human Resources: Connect with Your talent in the CloudCloud Integration for Human Resources: Connect with Your talent in the Cloud
Cloud Integration for Human Resources: Connect with Your talent in the Cloud
 
Oracle 12c New Features
Oracle 12c New FeaturesOracle 12c New Features
Oracle 12c New Features
 
Best Features of Multitenant 12c
Best Features of Multitenant 12cBest Features of Multitenant 12c
Best Features of Multitenant 12c
 
Why to Upgrade to Oracle 12c
Why to Upgrade to Oracle 12cWhy to Upgrade to Oracle 12c
Why to Upgrade to Oracle 12c
 
ADF 12c como Backend
ADF 12c como BackendADF 12c como Backend
ADF 12c como Backend
 
Improving the Performance of PL/SQL function calls from SQL
Improving the Performance of PL/SQL function calls from SQLImproving the Performance of PL/SQL function calls from SQL
Improving the Performance of PL/SQL function calls from SQL
 
Integracion Continua en Oracle ADF
Integracion Continua en Oracle ADFIntegracion Continua en Oracle ADF
Integracion Continua en Oracle ADF
 
Gestión de infraestructura tomcat/Tom EE con tfactory
Gestión de infraestructura tomcat/Tom EE con tfactoryGestión de infraestructura tomcat/Tom EE con tfactory
Gestión de infraestructura tomcat/Tom EE con tfactory
 
Pluggable Databases: What they will break and why you should use them anyway!
Pluggable Databases: What they will break and why you should use them anyway!Pluggable Databases: What they will break and why you should use them anyway!
Pluggable Databases: What they will break and why you should use them anyway!
 
Introduction to Oracle Clusterware 12c
Introduction to Oracle Clusterware 12cIntroduction to Oracle Clusterware 12c
Introduction to Oracle Clusterware 12c
 
What's next after Upgrade to 12c
What's next after Upgrade to 12cWhat's next after Upgrade to 12c
What's next after Upgrade to 12c
 
Upgrade/Migrate to Oracle 12c: Live and Uncensored!
Upgrade/Migrate to Oracle 12c: Live and Uncensored!Upgrade/Migrate to Oracle 12c: Live and Uncensored!
Upgrade/Migrate to Oracle 12c: Live and Uncensored!
 
How to Upgrade Hundreds or Thousands of Databases
How to Upgrade Hundreds or Thousands of DatabasesHow to Upgrade Hundreds or Thousands of Databases
How to Upgrade Hundreds or Thousands of Databases
 
Deep Dive: More Oracle Data Pump Performance Tips and Tricks
Deep Dive: More Oracle Data Pump Performance Tips and TricksDeep Dive: More Oracle Data Pump Performance Tips and Tricks
Deep Dive: More Oracle Data Pump Performance Tips and Tricks
 
How Oracle Single/Multitenant will change a DBA's life
How Oracle Single/Multitenant will change a DBA's lifeHow Oracle Single/Multitenant will change a DBA's life
How Oracle Single/Multitenant will change a DBA's life
 
Integration Cloud Service vs SOA
Integration Cloud Service vs SOAIntegration Cloud Service vs SOA
Integration Cloud Service vs SOA
 
SOA y Microservices Diferencias y Aplicaciones
SOA y Microservices Diferencias y AplicacionesSOA y Microservices Diferencias y Aplicaciones
SOA y Microservices Diferencias y Aplicaciones
 
It's raining data! Oracle databases in the cloud
It's raining data! Oracle databases in the cloudIt's raining data! Oracle databases in the cloud
It's raining data! Oracle databases in the cloud
 
The best Oracle Database 12c Tuning Features for Developers
The best Oracle Database 12c Tuning Features for DevelopersThe best Oracle Database 12c Tuning Features for Developers
The best Oracle Database 12c Tuning Features for Developers
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 

Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle

  • 1. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle Thomas Kyte http://asktom.oracle.com/
  • 2. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Statement Processing and the Optimizer What Happens when a SQL statement is issued? User Library Cache Shared SQL Area Shared Pool CnC1 C2 … 3 Cost Estimator Query Transformation Plan Generator Optimizer Oracle Database 1 Syntax Check Semantic Check Shared Pool check 2 Parsing 4 SQL Execution Code Generator Decision on what processing is offloaded occurs here
  • 3. <Insert Picture Here> What is an execution plan and how to generate one
  • 4. What is an Execution plan? • Execution plans show the detailed steps necessary to execute a SQL statement • These steps are expressed as a set of database operators that consumes and produces rows • The order of the operators and their implementation is decided by the optimizer using a combination of query transformations and physical optimization techniques • The display is commonly shown in a tabular format, but a plan is in fact tree-shaped
  • 5. Group By HASH JOIN TABLE ACCESS SALES TABLE ACCESS PRODUCTS What is an Execution plan? Query SELECT prod_category, avg(amount_sold) FROM sales s, products p WHERE p.prod_id = s.prod_id GROUP BY prod_category; Tabular representation of plan ----------------------------------------- Id Operation Name ----------------------------------------- 0 SELECT STATEMENT 1 HASH GROUP BY 2 HASH JOIN 3 TABLE ACCESS FULL PRODUCTS 4 PARTITION RANGE ALL 5 TABLE ACCESS FULL SALES ----------------------------------------- Tree-shaped representation of plan
  • 6. How to get an Execution Plan Two methods for looking at the execution plan 1.EXPLAIN PLAN command • Displays an execution plan for a SQL statement without actually executing the statement 2.V$SQL_PLAN • A dictionary view introduced in Oracle 9i that shows the execution plan for a SQL statement that has been compiled into a cursor in the cursor cache Use DBMS_XPLAN package to display plans Under certain conditions the plan shown with EXPLAIN PLAN can be different from the plan shown using V$SQL_PLAN
  • 7. How to get an Execution Plan Example 1 EXPLAIN PLAN command & dbms_xplan.display function SQL> EXPLAIN PLAN FOR SELECT prod_category, avg(amount_sold) FROM sales s, products p WHERE p.prod_id = s.prod_id GROUP BY prod_category; Explained SQL> SELECT plan_table_output FROM table(dbms_xplan.display('plan_table',null,'basic')); ------------------------------------------ Id Operation Name ------------------------------------------ 0 SELECT STATEMENT 1 HASH GROUP BY 2 HASH JOIN 3 TABLE ACCESS FULL PRODUCTS 4 PARTITION RANGE ALL 5 TABLE ACCESS FULL SALES -------------------------------------------
  • 8. Explain Plan “lies” • Explain plan should hardly ever be used… • You have to be careful when using autotrace and related tools • Never use “explain=u/p” with tkprof • Avoid dbms_xplan.display, use display_cursor
  • 9. Explain plan lies… ops$tkyte%ORA11GR2> create table t 2 as 3 select 99 id, to_char(object_id) str_id, a.* 4 from all_objects a 5 where rownum <= 20000; Table created. ops$tkyte%ORA11GR2> update t 2 set id = 1 3 where rownum = 1; 1 row updated. ops$tkyte%ORA11GR2> create index t_idx on t(id); Index created. ops$tkyte%ORA11GR2> create index t_idx2 on t(str_id); Index created.
  • 10. Explain plan lies… ops$tkyte%ORA11GR2> begin 2 dbms_stats.gather_table_stats 3 ( user, 'T', 4 method_opt=>'for all indexed columns size 254', 5 estimate_percent => 100, 6 cascade=>TRUE ); 7 end; 8 / PL/SQL procedure successfully completed.
  • 12. Explain plan lies… Need a volunteer select count(*) from t where id = :n; What cardinality would you estimate and why?
  • 13. Explain plan lies… ops$tkyte%ORA11GR2> variable n number ops$tkyte%ORA11GR2> exec :n := 1; PL/SQL procedure successfully completed. ops$tkyte%ORA11GR2> set autotrace on explain ops$tkyte%ORA11GR2> select count(subobject_name) from t where id = :n; --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 86 (0)| 00:00:02 | | 1 | SORT AGGREGATE | | 1 | 20 | | | |* 2 | TABLE ACCESS FULL| T | 10000 | 195K| 86 (0)| 00:00:02 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("ID"=TO_NUMBER(:N)) <<<<===== to_number?
  • 14. Explain plan lies… ops$tkyte%ORA11GR2> select * from table(dbms_xplan.display_cursor('98mx7jbn7jpm8', '', '+peeked_binds')); select count(subobject_name) from t where id = :n -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | SORT AGGREGATE | | 1 | 20 | | | | 2 | TABLE ACCESS BY INDEX ROWID| T | 1 | 20 | 2 (0)| 00:00:01 | |* 3 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Peeked Binds (identified by position): -------------------------------------- 1 - :N (NUMBER): 1 Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("ID"=:N)
  • 15. Explain plan lies… ops$tkyte%ORA11GR2> set autotrace traceonly explain ops$tkyte%ORA11GR2> select object_id from t where str_id = :n; -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 19 | 2 (0)| 00:0 | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 19 | 2 (0)| 00:0 |* 2 | INDEX RANGE SCAN | T_IDX2 | 1 | | 1 (0)| 00:0 -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("STR_ID"=:N) <<== interesting…
  • 16. Explain plan lies… ops$tkyte%ORA11GR2> select object_id from t where str_id = :n; OBJECT_ID ---------- 99 ops$tkyte%ORA11GR2> select * from table(dbms_xplan.display_cursor); -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 86 (100)| | |* 1 | TABLE ACCESS FULL| T | 1 | 19 | 86 (0)| 00:00:02 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(TO_NUMBER("STR_ID")=:N) <<= string has to convert..
  • 17. Explain plan lies… 1 - filter(TO_NUMBER("STR_ID")=:N) <<= string has to convert.. STR_ID ------ 0 00 000 0.00 +0 -0 1,000 1.000
  • 18. How to get an Execution Plan Example 2 Generate & display execution plan for the last SQL stmts executed in a session SQL>SELECT prod_category, avg(amount_sold) FROM sales s, products p WHERE p.prod_id = s.prod_id GROUP BY prod_category; no rows selected SQL> SELECT plan_table_output FROM table(dbms_xplan.display_cursor(null,null,'basic')); ------------------------------------------ Id Operation Name ------------------------------------------ 0 SELECT STATEMENT 1 HASH GROUP BY 2 HASH JOIN 3 TABLE ACCESS FULL PRODUCTS 4 PARTITION RANGE ALL 5 TABLE ACCESS FULL SALES -------------------------------------------
  • 19. How to get an Execution Plan Example 3 Displaying execution plan for any other statement from V$SQL_PLAN 1.Directly: SQL> SELECT plan_table_output FROM table(dbms_xplan.display_cursor('fnrtqw9c233tt',null,'basic')); 2.Indirectly: SQL> SELECT plan_table_output FROM v$sql s, TABLE(dbms_xplan.display_cursor(s.sql_id,s.child_number, 'basic')) t WHERE s.sql_text like 'select PROD_CATEGORY%';
  • 20. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • So what operations can actually be offloaded? – Full table scan – Fast full index scan of a B-Tree or bitmap index – Bloom filters • But not all predicates can be offloaded – V$SQLFN_METADATA has a column called offloadable – Indicates if SQL function is offloadable or not – With each new release more function can be offloaded – For example TRUNC is but RANK is not offloadable History
  • 21. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • The plan always shows an eligible operation is offloaded History The display of the word STORAGE is actually controlled by the parameter cell_offload_plan_display it is not an indication that offloading will or has occurred, just that it is possible
  • 22. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • The plan always shows an eligible operation is offloaded History The word STORAGE in the predicate information is controlled by another internal optimizer parameter
  • 23. <Insert Picture Here> What is a good plan for the optimizer
  • 24. What’s a Good Plan for the Optimizer? The Optimizer has two different goals • Serial execution: It’s all about cost • The cheaper, the better • Parallel execution: it’s all about performance • The faster, the better Two fundamental questions: • What is cost? • What is performance?
  • 25. What is Cost? • A magically number the optimizer makes up? • Resources required to execute a SQL statement? • Result of complex calculations? • Estimate of how long it will take to execute a statement? Actual Definition • Cost represents units of work or resources used • Optimizer uses CPU & memory usage plus IO as units of work • Cost is an estimate of the amount of CPU and memory plus the number of disk I/Os, used in performing an operation Cost is an internal Oracle measurement
  • 26. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> create table organized 2 as 3 select x.* 4 from (select * from stage order by object_name) x 5 / Table created. ops$tkyte%ORA11GR2> create table disorganized 2 as 3 select x.* 4 from (select * from stage order by dbms_random.random) x 5 / Table created.
  • 27. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> create index organized_idx on organized(object_name); Index created. ops$tkyte%ORA11GR2> create index disorganized_idx on disorganized(object_name); Index created.
  • 28. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> begin 2 dbms_stats.gather_table_stats 3 ( user, 'ORGANIZED', 4 estimate_percent => 100, 5 method_opt=>'for all indexed columns size 254' 6 ); 7 dbms_stats.gather_table_stats 8 ( user, 'DISORGANIZED', 9 estimate_percent => 100, 10 method_opt=>'for all indexed columns size 254' 11 ); 12 end; 13 / PL/SQL procedure successfully completed.
  • 29. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> select table_name, blocks, num_rows, 0.05*num_rows, 0.10*num_rows from user_tables 2 where table_name like '%ORGANIZED' order by 1; TABLE_NAME BLOCKS NUM_ROWS 0.05*NUM_ROWS 0.10*NUM_ROWS ------------------------------ ---------- ---------- ------------- ------------- DISORGANIZED 1062 72774 3638.7 7277.4 ORGANIZED 1062 72774 3638.7 7277.4 ops$tkyte%ORA11GR2> select table_name, index_name, clustering_factor from user_indexes 2 where table_name like '%ORGANIZED' order by 1; TABLE_NAME INDEX_NAME CLUSTERING_FACTOR ------------------------------ ------------------------------ ----------------- DISORGANIZED DISORGANIZED_IDX 72727 ORGANIZED ORGANIZED_IDX 1036
  • 30. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> select /*+ index( organized organized_idx) */ 2 count(subobject_name) 3 from organized; COUNT(SUBOBJECT_NAME) --------------------- 542 ops$tkyte%ORA11GR2> select /*+ index( disorganized disorganized_idx) */ 2 count(subobject_name) 3 from disorganized; COUNT(SUBOBJECT_NAME) --------------------- 542
  • 31. Clustering Factor and Cost Example select /*+ index( organized organized_idx) */ count(subobject_name) from organized 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.45 0.45 1036 1398 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.45 0.46 1036 1398 0 1 Row Source Operation --------------------------------------------------- SORT AGGREGATE (cr=1398 pr=1036 pw=0 time=456653 us) TABLE ACCESS BY INDEX ROWID ORGANIZED (cr=1398 pr=1036 pw=0 time=376835 us cos… INDEX FULL SCAN ORGANIZED_IDX (cr=362 pr=0 pw=0 time=98362 us cost=363 … 1,398-362 = 1,036 - the Clustering Factor and Cost Example…
  • 32. Clustering Factor and Cost Example select /*+ index( disorganized disorganized_idx) */ count(subobject_name) from disorganized 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.83 0.83 1036 73089 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.83 0.83 1036 73089 0 1 Row Source Operation --------------------------------------------------- SORT AGGREGATE (cr=73089 pr=1036 pw=0 time=835554 us) TABLE ACCESS BY INDEX ROWID DISORGANIZED (cr=73089 pr=1036 pw=0 time=750651 us … INDEX FULL SCAN DISORGANIZED_IDX (cr=362 pr=0 pw=0 time=96421 us cost=363 … 73,089-362 = 72,727 - the Clustering Factor and Cost Example…
  • 33. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> select * from organized where object_name like 'F%'; Execution Plan ---------------------------------------------------------- Plan hash value: 1925627673 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CP ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 149 | 14453 | 6 ( | 1 | TABLE ACCESS BY INDEX ROWID| ORGANIZED | 149 | 14453 | 6 ( |* 2 | INDEX RANGE SCAN | ORGANIZED_IDX | 149 | | 3 ( ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_NAME" LIKE 'F%') filter("OBJECT_NAME" LIKE 'F%')
  • 34. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> select * from disorganized where object_name like 'F%'; Execution Plan ---------------------------------------------------------- Plan hash value: 3767053355 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost ( ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 149 | 14453 | 152 | 1 | TABLE ACCESS BY INDEX ROWID| DISORGANIZED | 149 | 14453 | 152 |* 2 | INDEX RANGE SCAN | DISORGANIZED_IDX | 149 | | 3 ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_NAME" LIKE 'F%') filter("OBJECT_NAME" LIKE 'F%')
  • 35. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> select * from organized where object_name like 'A%'; Execution Plan ---------------------------------------------------------- Plan hash value: 1925627673 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CP ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1824 | 172K| 38 ( | 1 | TABLE ACCESS BY INDEX ROWID| ORGANIZED | 1824 | 172K| 38 ( |* 2 | INDEX RANGE SCAN | ORGANIZED_IDX | 1824 | | 12 ( ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_NAME" LIKE 'A%') filter("OBJECT_NAME" LIKE 'A%')
  • 36. Clustering Factor and Cost Example ops$tkyte%ORA11GR2> select * from disorganized where object_name like 'A%'; Execution Plan ---------------------------------------------------------- Plan hash value: 2727546897 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1824 | 172K| 290 (1)| 00:00:0 |* 1 | TABLE ACCESS FULL| DISORGANIZED | 1824 | 172K| 290 (1)| 00:00:0 ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OBJECT_NAME" LIKE 'A%')
  • 37. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. ‘Regular’ and Exadata plans and the Optimizer Overview Optimizer selects the wrong plan because Incorrect cardinality estimate Not accounting correctly for speed of scans
  • 38. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Overview Optimizer selects the wrong plan because Incorrect cardinality estimate Not accounting correctly for speed of scans
  • 40. SQL Execution Plan When looking at a plan can you determine if the following is correct? • Cardinality • Are the correct number of rows coming out of each object? • Access paths • Is the data being accessed in the best way? Scan? Index lookup? • Join order • Are tables being joined in the correct order to eliminate as much data as early as possible? • Join type • Are the right join types being used? • Partitioning pruning • Did I get partition pruning? Is it eliminating enough data? • Parallelism
  • 41. Cardinality What is it? • Estimate of number rows that will be returned • Cardinality for a single value predicate = num_rows total / num_distinct total • E.g. 100 rows total, 10 distinct values => cardinality=10 rows • OR if histogram present num_rows * Density Why should you care? • Influences everything! Access method, Join type, Join Order etc What causes Cardinality to be wrong? • Stale or no statistics • Data Skews • Multiple single column predicates on a table • A function wrapped where clause predicate • Complicated expressions that contain columns from different tables
  • 42. “Wrong Plan => Wrong Cardinality”
  • 43. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> create table t 2 as select decode( mod(rownum,2), 0, 'N', 'Y' ) flag1, 3 decode( mod(rownum,2), 0, 'Y', 'N' ) flag2, a.* 4 from all_objects a 5 / Table created. ops$tkyte%ORA11GR2> create index t_idx on t(flag1,flag2); Index created. ops$tkyte%ORA11GR2> begin 2 dbms_stats.gather_table_stats 3 ( user, 'T', 4 method_opt=>'for all indexed columns size 254' ); 5 end; 6 / PL/SQL procedure successfully completed.
  • 44. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> select 'select * from t', num_rows 2 from user_tables where table_name = 'T' 3 union all 4 select 'select * from t where flag1 = "N"', num_rows/2 5 from user_tables where table_name = 'T' 6 union all 7 select 'select * from t where flag2 = "N"', num_rows/2 8 from user_tables where table_name = 'T' 9 union all 10 select 'select * from t where flag1 = "N" and flag2 = "N"', num_rows/2/2 11 from user_tables where table_name = 'T'; 'SELECT*FROMT' NUM_ROWS ------------------------------------------------- ---------- select * from t 72726 select * from t where flag1 = "N" 36363 select * from t where flag2 = "N" 36363 select * from t where flag1 = "N" and flag2 = "N" 18181.5
  • 45. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> set autotrace traceonly explain ops$tkyte%ORA11GR2> select * from t where flag1='N'; Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 36499 | 3635K| 301 (1)| 00:00:04 | |* 1 | TABLE ACCESS FULL| T | 36499 | 3635K| 301 (1)| 00:00:04 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("FLAG1"='N')
  • 46. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> select * from t where flag2='N'; Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 36227 | 3608K| 301 (1)| 00:00:04 | |* 1 | TABLE ACCESS FULL| T | 36227 | 3608K| 301 (1)| 00:00:04 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("FLAG2"='N')
  • 47. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> select * from t where flag1='N' and flag2='N'; Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 18181 | 1810K| 301 (1)| 00:00:04 | |* 1 | TABLE ACCESS FULL| T | 18181 | 1810K| 301 (1)| 00:00:04 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("FLAG2"='N' AND "FLAG1"='N')
  • 48. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> select /*+ gather_plan_statistics */ * 2 from t where flag1='N' and flag2='N'; no rows selected
  • 49. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.02 | 1080 | |* 1 | TABLE ACCESS FULL| T | 1 | 18181 | 0 |00:00:00.02 | 1080 | ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(("FLAG2"='N' AND "FLAG1"='N')) 19 rows selected.
  • 50. Wrong Plan => Wrong Cardinality ops$tkyte%ORA11GR2> select /*+ dynamic_sampling(t 3) */ * from t where flag1='N' and flag2='N'; Execution Plan ---------------------------------------------------------- Plan hash value: 470836197 ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 6 | 612 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 6 | 612 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | T_IDX | 6 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("FLAG1"='N' AND "FLAG2"='N') Note ----- - dynamic sampling used for this statement (level=2)
  • 51. Wrong Plan => Wrong Cardinality SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false') NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:"SYS_B_00"), NVL(SUM(C2),:"SYS_B_01"), NVL(SUM(C3),:"SYS_B_02") FROM (SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("T") FULL("T") NO_PARALLEL_INDEX("T") */ :"SYS_B_03" AS C1, CASE WHEN "T"."FLAG1"= :"SYS_B_04" AND "T"."FLAG2"=:"SYS_B_05" THEN :"SYS_B_06" ELSE :"SYS_B_07" END AS C2, CASE WHEN "T"."FLAG2"=:"SYS_B_08" AND "T"."FLAG1"=:"SYS_B_09“ THEN :"SYS_B_10" ELSE :"SYS_B_11" END AS C3 FROM "OPS$TKYTE"."T" SAMPLE BLOCK (:"SYS_B_12" , :"SYS_B_13") SEED (:"SYS_B_14") "T") SAMPLESUB
  • 52. Check Cardinality using SELECT /*+ gather_plan_statistics */ p.prod_name as product, sum(s.quantity_sold) as units, FROM sales s, products p WHERE s.prod_id =p.prod_id GROUP BY p.prod_name; SELECT * FROM table ( DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST')); compare the estimated number of rows returned for each operation in the plan to actual rows returned
  • 53. Check Cardinality using SQL Monitor SQL Monitor allows you to compare the estimated number of rows returned for each operation in the plan to actual rows returned
  • 54. Suggestions for fixing Cardinality issues Cause Solution Stale or no statistics DBMS_STATS Data Skew Create a histogram* Multiple single column predicates on a table Create a column group using DBMS_STATS.CREATE_EXTENDED_STATS Multiple columns used in a join Create a column group using DBMS_STATS.CREATE_EXTENDED_STATS Function wrapped column Create statistics on the function wrapped column using DBMS_STATS.CREATE_EXTENDED_STATS Complicated expression containing columns from multiple tables Use dynamic sampling level 4 or higher
  • 55. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Why the Optimizer picks the wrong plan broken down by the percentage Incorrect cardinality estimate Not accounting correctly for speed of scans Not accounting for HCC decompression • More than 85% of the plan problems reported on Exadata are caused by Incorrect cardinality estimates • Fix cardinality estimates before trying any other tuning techniques • Typically fixing the cardinality estimates achieves the desired plan
  • 56. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Overview Optimizer selects the wrong plan because Incorrect cardinality estimate Not accounting correctly for speed of scans Complex Expressions Incomplete stats Stale Stats
  • 57. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Non-Exadata System: Indexes vs. FTS Not accounting for speed of scans • On a non-Exadata system the cost of a full table scan far out weighs the cost of an index range scan or even a fast full index scan Rows Full Table Scan Index Scan Cost
  • 58. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Non-Exadata System: Indexes vs. FTS Not accounting for speed of scans • On a non-Exadata system the cost of a full table scan far out weighs the cost of an index range scan or even a fast full index scan • Typically the elapse times follows suit Rows Full Table Scan Index Scan Time
  • 59. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Exadata System: Indexes vs. FTS Not accounting for speed of scans Rows Full Table Scan Index Scan • On an Exadata system the cost of the full table scan still exceeds the cost of an index scan CostTime • BUT in reality the elapse time can often be much faster
  • 60. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • TEST_TBL table contains 20 million rows – 22 Columns consisting of numbers and string data types • Compressed using HCC query high • Index created on UK column – This is a unique index – Values range from 1 to 20 million Not accounting correctly for the speed of scan
  • 61. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Query: Create table <name> as Select * from test_tbl t where UK <= :VAL; Default plan is index range scan Elapse time is 13.33 seconds Not accounting for speed of scans
  • 62. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Query: Create table <name>as Select /*+ full(t) */ * from test_tbl t where UK <= :VAL; Forced plan is full table scan Elapse time is 5.8 seconds Not accounting for speed of scans
  • 63. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • So the answer is simple • Drop all of the indexes • Everything will be faster via a full table scan Not accounting for speed of scans • Not so fast • What happens when you have multiple concurrent users?
  • 64. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Non-Exadata Exadata Exadata and the Optimizer Performance of concurrent Full Table scan Not accounting for speed of scans # of concurrent scans • With Exadata the number of concurrent scan operations that can be sustained before the elapse time gets too high is greater due to offload • Predicate push-down • Column projection • But at some point it stops scaling • Optimizer needs to be aware of this too Time
  • 65. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • How can you influence the Optimizer to pick a full table scan even with an index present? Not accounting for speed of scans • DO NOT use OPTIMIZER_INDEX_COST_ADJ • It doesn’t influence full table scan cost • It is a multiplier on the cost of an index access • Setting it to 400 makes the index cost jump 4X from 2028 to 8114
  • 66. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer • Better to look at statistics that influence Optimizer’s decisions • Cost of scan determined by Number of blocks to read MBRC • What is Multi Block Read Count (MBRC)? – Number of db blocks read in a single OS read command – On Exadata one OS read is 1MB of data or 128 8KB db blocks Not accounting correctly for the speed of scan But the Optimizer uses MBRC of 8 by default
  • 67. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Not accounting correctly for the speed of scan • System statistics tell the Optimizer about the speed of IO on a system • By default system statistics does not gather MBRC • Only buffer IO are monitored • Direct path IO are excluded
  • 68. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Accounting correctly for the speed of scan • New GATHER_SYSTEM_STATS mode exclusively for EXADATA • Monitors and captures MBRC • For 8KB block size captures 128 • New method for monitoring IOTFRSPEED • Captures roughly 200MB per second per process
  • 69. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Default plans after exec dbms_stats.gather_system_stats('EXADATA'); Accounting for speed of scans Cost of full table scan is now lower than the index range scan of 21120
  • 70. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Query: Select * from test_tbl where UK <= :VAL; Full table scan plan with default system statistics Full table scan plan with EXADATA system statistics Accounting for speed of scans
  • 71. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Exadata System: Indexes vs. FTS Accounting for speed of scans • With the correct system statistics in place the cost for a full table scan more accurately reflects the expected performance • This will not prevent the Optimizer from selecting an index • It just lowers the inflection point where the plan will switch from an index access to a full table scan Rows Full Table Scan Index Scan Cost
  • 72. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Overview Optimizer selects the wrong plan because Incorrect cardinality estimate Not accounting correctly for speed of scans Complex Expressions Incomplete stats Stale Stats By default Optimizer assumes MBRC = 8
  • 73. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Exadata and the Optimizer Overview Optimizer selects the wrong plan because Incorrect cardinality estimate Not accounting correctly for speed of scans Complex Expressions Incomplete stats Stale Stats By default Optimizer assumes MBRC = 8
  • 74. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. More Information • White papers – Technical overview of the Exadata Database Machine – What to expect from the Oracle Optimizer in 11g • Optimizer Blog – http://blogs.oracle.com/optimizer • Oracle.com – http://www.oracle.com/us/products/database/exadata/overview/in dex.html – http://www.oracle.com/technetwork/database/focus-areas/bi- datawarehousing/dbbi-tech-info-optmztn-092214.html
  • 75. Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Q&A
  • 76. Copyright © 2012, Oracle and/or its affiliates. All rights reserved.