Adrian Buboi
Senior Oracle DBA, SCC Services Romania
DBA Lounge Iasi: 17-10-2013
 Definition and evolution

 Method
 Object statistics
 System statistics
 Parameters used by the Optimizer
 Cost calculation example
2
• “The optimizer is built-in software that determines the most efficient way to execute a
SQL statement.” - Oracle® Database Performance Tuning Guide 11g Release 2 (11.2)

INPUTS
SELECT /*+ FULL(T) */ T.*
FROM Table T
WHERE . . .

OPTIMIZER
With its mathematical model
containing logic and default
assumptions

*already parsed by parser

• Optimizer parameters

EXECUTION
PLAN

• System statistics
• Object statistics

A C T I O N S

(with the lowest
estimated cost)

• Performs query transformations (view merging, predicate
pushing, subquery unnesting, query rewrite with MVs, etc)
• Computes multiple possible execution plans together with
their estimated cost
3
• RBO = Rule Based Optimizer, predecessor of CBO
• CBO = Cost Based Optimizer
• RBO considered only the number of read requests, and used a set of predefined rules for deciding the best execution plan – these
made it predictable and consistently produced the same execution plan
• But, those fixed rules (e.g. single block read takes as much as multiblock, it is always better to use an index than to FTS) did not
apply in plenty situations, so
• CBO improved the situation, taking into account the size of read requests, time taken by read requests, CPU consumed, effect of
caching
• COST = the Optimizer estimated resource usage for a given plan; the lower the cost, the more efficient an execution plan is
expected to be

The beginning of
Oracle database

Oracle v7

Oracle v8i

Oracle v9iR2

Oracle v10gR2

Oracle v11gR2

End of the 1970s

1992

1999

2002

2005

2009

1988

1997

2001

2003

2007

Oracle v6

Oracle v8

Oracle v9i

Oracle v10g

Oracle v11g

Cardinality
feedback

Peace and quiet all around … or not?

Bind variable
peeking
RBO de-supported

CBO default
Stored Outlines

Advanced
Cursor Sharing

SQL Profiles

2013

Auto adjusted
Dynamic Sampling

Oracle v12c

Adaptive Query
Optimization

Direct path reads for
serial table scans
SQL Plan Management – SQL Plan Baselines

CBO - CPU
costing

RBO – IO costing

4

* What would you preffer: fixed plans performing consistently less-than-best-performant over time, or changing plans giving best performance together with less-than-best-performance?
What is wrong with the cost figure from execution plan?
(sometimes, but enough times to make us go crazy!)

Join Type

Cost from Explain Plan

Execution Time

Nested Loop

n

HOURS

Hash Join

n x 100000

seconds

* NO, the statement does NOT contain bind variables
** YES, the results are consistently repeatable, so no workload variation root cause
*** Object statistics (histograms and extended statistics included) collected

What could be the CBOs excuses?
• Data statistics lie to CBO just enough to make him go south
• CBO knows about the data just what object statistics tell him
• System statistics lie to CBO just enough to make him go south
• CBO knows about the underlying hardware just what system statistics tell him

• Workload on the system at query execution time is not known when CBO computes the
execution plan
• One of the recent Oracle shots to alleviate the above is the new Oracle 12c
feature - Adaptive Query Optimization
• There is no such thing as perfect software , and CBO is no exception: it contains
shortcomings, not-always-correct assumptions and bugs
• Oracle tries to address the above with every new major release, patch set ,
5
patch set update, one-off fixes, but they still keep coming!
• Oracle 10053 Event trace = generates a trace file containing Optimizer’s actions when
generating an Execution Plan
• Traced simple query: SELECT … FROM on Oracle 11.2.0.3 EE 64bit on top of Oracle
Linux Server 6.3
DBMS_SYSTEM.SET_EV(si=>123, se=>1234, ev=>10053, le=>1, nm=>' ');
ALTER SESSION SET events '10053 trace name context forever, level 1';
ALTER SESSION SET events 'trace[rdbms.SQL_Optimizer.*][sql:SQL_ID]';

• Sections of interest from the trace file:
• Legend = abbreviations used by optimizer trace
• Parameters used by the optimizer [including Bug Fix Control Environment]
• Query Transformations
• Peeked values of the binds in SQL statement
• System statistics information
• Base statistical information [Object statistics]
• Access path analysis (includes Cost)
• Optimizer statistics and computations [General Plans, Join Permutations,
Execution Plan – includes Cost]

6
New diagnostic events infrastructure

C /C++ module names which can
be seen in OS stack traces of
Oracle process (e.g. using

SQL> oradebug doc component SQL_Compiler
SQL_Compiler
SQL Compiler
)
SQL_Parser
SQL Parser (qcs)
SQL_Semantic
SQL Semantic Analysis (kkm)
SQL_Optimizer
SQL Optimizer
SQL_Transform
SQL Transformation (kkq, vop, nso)
SQL_MVRW
SQL Materialized View Rewrite
SQL_VMerge
SQL View Merging (kkqvm)
SQL_Virtual
SQL Virtual Column (qksvc, kkfi)
SQL_APA
SQL Access Path Analysis (apa)
SQL_Costing
SQL Cost-based Analysis (kko, kke)
SQL_Parallel_Optimization SQL Parallel Optimization (kkopq)
SQL_Code_Generator
SQL Code Generator (qka, qkn, qke, kkfd, qkx)
SQL_Parallel_Compilation SQL Parallel Compilation (kkfd)
SQL_Expression_Analysis SQL Expression Analysis (qke)
SQL_Plan_Management
SQL Plan Managment (kkopm)
MPGE
MPGE (qksctx)

pstack

7
• Describe the database data
• Types: table, column, index statistics
• Besides user schemas objects, they can also be gathered against:
• Oracle dictionary tables
• Oracle fixed tables (which are in fact memory structures and not real tables)
• DBMS_STATS is the tool to work with statistics
• Oracle nightly statistics gathering default job – collects stats on tables with no / stale
statistics
• Does NOT collect fixed table statistics – these should be gathered manually
• Besides gathered, statistics can be locked, compared, moved between databases,
deleted
• Can be manually set to desired values
• Have configurable retention
• Statistics operations performed at database/schema level are instrumented in
DBA_OPSTAT_OPERATIONS

8
Table statistics
SELECT num_rows, blocks, avg_row_len,
to_char(last_analyzed, 'dd.mm.yyyy hh24:mi') as last_analyzed,
sample_size
FROM USER_TABLES
WHERE table_name = 'PEOPLE';

NUM_ROWS
BLOCKS AVG_ROW_LEN LAST_ANALYZED
SAMPLE_SIZE
---------- ---------- ----------- ---------------- ----------10000
197
127 15.10.2013 15:35
10000

• Should be kept relevant / up to date

9
Column statistics
SELECT column_name, num_distinct, low_value, high_value, density, num_nulls,
avg_col_len, histogram, num_buckets,
to_char(last_analyzed, 'dd.mm.yyyy hh24:mi') as last_analyzed, sample_size
FROM USER_TAB_COL_STATISTICS
WHERE table_name = 'PEOPLE';

COLUMN_NAME NUM_DISTINCT LOW_VALUE
HIGH_VALUE
DENSITY NUM_NULLS AVG_COL_LEN LAST_ANALYZED
----------- ------------ ------------ ------------------ ---------- --------- ----------- ---------------ID
10000 C102
C302
.0001
0
4 15.10.2013 19:06
NAME
9998 4E616D652030 4E616D652039393937 .00010002
0
10 15.10.2013 19:06
AGE
71 C102
C148
.014084507
0
3 15.10.2013 19:06
GENDER
2 46
4D
.5
0
2 15.10.2013 19:06
CITY
10 436974792031 436974792039
.1
0
8 15.10.2013 19:06

Number between 0 and 1
With no histograms: 1/num_distinct
With histograms: depend on histogram type
Min and Max values in internal representation format
Can be translated to human-readable values using utl_raw
and dbms_stats.covert_raw_* procedures

• Histograms
• Extended statistics – object statistics about expressions and/or groups of columns

10
Index statistics
SELECT index_name, blevel, leaf_blocks, distinct_keys, num_rows, clustering_factor,
avg_leaf_blocks_per_key, avg_data_blocks_per_key, to_char(last_analyzed, 'dd.mm.yyyy
hh24:mi') as last_analyzed
FROM user_ind_statistics
WHERE table_name = 'PEOPLE';
INDEX_NAME BLEVEL LEAF_BLOCKS DISTINCT_KEYS NUM_ROWS CLUSTERING_FACTOR AVG_LEAF_BLOCKS_PER_KEY AVG_DATA_BLOCKS_PER_KEY LAST_ANALYZED
---------- ------ ----------- ------------- -------- ----------------- ----------------------- ----------------------- ---------------PK_PEOPLE
1
20
10000
10000
185
1
1 15.10.2013 19:37

Root block

Branch block

Leaf block

Leaf block

Leaf block

Branch block

Leaf block

Leaf block

Leaf block
SELECT * FROM sys.aux_stats$;

NOWORKLOAD statistics
SNAME
------------SYSSTATS_INFO
SYSSTATS_INFO
SYSSTATS_INFO
SYSSTATS_INFO
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN

PNAME
PVAL1 PVAL2
---------- ---------- ---------------STATUS
COMPLETED
DSTART
09-17-2011 10:21
DSTOP
09-17-2011 10:21
FLAGS
1
CPUSPEEDNW 1751.75879
IOSEEKTIM
10
IOTFRSPEED
4096
SREADTIM
MREADTIM
CPUSPEED
MBRC
MAXTHR
SLAVETHR

• Always-available by default since 10g
DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode=> noworkload’)

• Oracle generates workload for both CPU and I/O benchmarks –
so stats need to be gathered when the system is idle
Millions of operations per second a CPU can process
Average time (in milliseconds) to locate data on disk (default 10)
Average number of bytes per millisecond that can be transferred
from the disk (default 4096)
Average time (in milliseconds) taken by a single block read
Average time (in milliseconds) taken by a multiblock read
Average number of blocks read during a multiblock read
Maximum I/O throughput (bytes/s) of the system

Possible approach:
Gather system statistics for several days and either
• Leave them in place, or
• Manually set them to averages / max values
computed from collected data
dbms_stats.set_system_stats

Average I/O throughput (bytes/s) of a parallel processing slave

WORKLOAD statistics
DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode
DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode
DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode
interval

=>
=>
=>
=>

‘start’)
‘stop’)
‘interval’,
30)

• Oracle does not generate workload for I/O benchmark – so stats
need to be gathered during a representative workload

I/O and CPU performance about the system Oracle engine runs on

12
321 parameters in the 10053 Optimizer trace file
• 64 we can fiddle with on prod without asking Oracle Support
• 257 hidden
•
•
•
•
•
•
•
•

OPTIMIZER_MODE [default: ALL_ROWS; other values: first_rows_[1 | 10 | 100 | 1000] | first_rows]
DB_FILE_MULTIBLOCK_READ_COUNT [see next slides]
OPTIMIZER_DYNAMIC_SAMPLING [default value: 2; range of values: 0 - 10]
OPTIMIZER_FEATURES_ENABLE [default value: 11.2.0.1; range of values: 8.0.0 … 11.2.0.1]
QUERY_REWRITE_ENABLED [default: true]
QUERY_REWRITE_INTEGRITY [default: enforced]
STAR_TRANSFORMATION_ENABLED [default: false]
PGA_AGGREGATE_TARGET (WORKAREA_SIZE_POLICY = AUTO) [default: MAX(10Mb,
20% of SGA size)]

• BITMAP_MERGE_AREA_SIZE, HASH_AREA_SIZE , SORT_AREA_SIZE,
SORT_AREA_RETAIN (WORKAREA_SIZE_POLICY = MANUAL)
• OPTIMIZER_INDEX_CACHING [default: 0, range of values: 0 - 100]
• OPTIMIZER_INDEX_COST_ADJ [default: 100, range of values: 1 - 10000]
• PARALLEL_*
13
The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey
Official documentation quotes:
<q>
DB_FILE_MULTIBLOCK_READ_COUNT is one of the parameters you can use to minimize
I/O during table scans. It specifies the maximum number of blocks read in one I/O
operation during a sequential scan.
[…]
As of Oracle Database 10g release 2, the default value of this parameter is a value that
corresponds to the maximum I/O size that can be performed efficiently. This value is
platform-dependent and is 1MB for most platforms.
[…]
Note that if the number of sessions is extremely large the multiblock read count value is
decreased to avoid the buffer cache getting flooded with too many table scan buffers.
[…]
Even though the default value may be a large value, the optimizer will not favor large
plans if you do not set this parameter. It would do so only if you explicitly set this
parameter to a large value.
</q>
Oracle® Database Reference 11g Release 2 (11.2)
14
The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey
DB_FILE_MULTIBLOCK_READ_COUNT does not always reads contiguous blocks! Why?
• blocks in buffer cache (dirty or current, does not matter) are not read from I/O subsystem
• physical multiblock reads do not cross extent boundaries
• segment headers are read using single block reads

ALTER SYSTEM SET db_file_multiblock_read_count = 10;
alter session set tracefile_identifier='sql_trace_5';
exec dbms_monitor.session_trace_enable(waits => true);
select * from people;
exec dbms_monitor.session_trace_disable;
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT
WAIT

#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:
#139960512564400:

nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db
nam='db

file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file

scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered
scattered

read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'
read'

ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=
ela=

335 file#=4 block#=171 blocks=5 obj#=78893 tim=1381952652556960
58 file#=4 block#=176 blocks=8 obj#=78893 tim=1381952652560928
111 file#=4 block#=185 blocks=7 obj#=78893 tim=1381952652564213
197 file#=4 block#=192 blocks=8 obj#=78893 tim=1381952652567468
211 file#=4 block#=201 blocks=7 obj#=78893 tim=1381952652570871
714 file#=4 block#=208 blocks=8 obj#=78893 tim=1381952652574104
282 file#=4 block#=217 blocks=7 obj#=78893 tim=1381952652577456
261 file#=4 block#=224 blocks=8 obj#=78893 tim=1381952652580403
258 file#=4 block#=233 blocks=7 obj#=78893 tim=1381952653556908
129 file#=4 block#=240 blocks=8 obj#=78893 tim=1381952653561688
202 file#=4 block#=249 blocks=7 obj#=78893 tim=1381952653565008
149 file#=4 block#=256 blocks=8 obj#=78893 tim=1381952653567697
153 file#=4 block#=265 blocks=7 obj#=78893 tim=1381952653571069
112 file#=4 block#=272 blocks=8 obj#=78893 tim=1381952653573783
167 file#=4 block#=281 blocks=7 obj#=78893 tim=1381952653576354
325 file#=4 block#=288 blocks=8 obj#=78893 tim=1381952653579429
161 file#=4 block#=386 blocks=10 obj#=78893 tim=1381952654688751
41 file#=4 block#=396 blocks=10 obj#=78893 tim=1381952654692630
105 file#=4 block#=406 blocks=10 obj#=78893 tim=1381952654696428
104 file#=4 block#=416 blocks=10 obj#=78893 tim=1381952654699846
98 file#=4 block#=426 blocks=10 obj#=78893 tim=1381952654703829
155 file#=4 block#=436 blocks=10 obj#=78893 tim=1381952655808778
238 file#=4 block#=446 blocks=7 obj#=78893 tim=1381952655814160

15
The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey
From OS
strace –pPID
readv(258, [{"624200253001~213*00024210223001000-410v213*0"..., 8192},
{"624200254001~213*00024k1001000-410v213*0"..., 8192}, {"624200255001~213*00024372323001000410v213*0"..., 8192}, {"624200256001~213*00024G.001000-410v213*0"..., 8192},
{"624200257001~213*00024272212001000-410v213*0"..., 8192}], 5) = 40960
readv(258, [{"624200260001~213*00024@=001000-410v213*0"..., 8192},
{"624200261001~213*00024315324001000-410v213*0"..., 8192},
{"624200262001~213*0002417722001000-410v213*0"..., 8192},
{"624200263001~213*00024214235001000-410v213*0"..., 8192}, {"624200264001~213*00024l25001000410v213*0"..., 8192}, {"624200265001~213*00020045W001000-410v213*0"..., 8192},
{"624200266001~213*00024235274001000-410v213*0"..., 8192}, {"624200267001~213*00024A9001000410v213*0"..., 8192}], 8) = 65536
readv(258, [{"624200271001200213*00024255352001000-410v213*0"..., 8192},
{"624200272001200213*00024~U001000-410v213*0"..., 8192},
{"624200273001200213*00024355263001000-410v213*0"..., 8192},
{"624200274001200213*00024[l001000-410v213*0"..., 8192},
{"624200275001200213*00024222310001000-410v213*0"..., 8192},
{"624200276001200213*00024Y364001000-410v213*0"..., 8192},
{"624200277001200213*000242720001000-410v213*0"..., 8192}], 7) = 57344
readv(258, […], 8) = 65536
readv(258, […], 7) = 57344
readv(258, […], 8) = 65536
readv(258, […], 7) = 57344
readv(258, […], 8) = 65536
readv(258, […], 7) = 57344
readv(258, […], 8) = 65536
readv(258, […], 7) = 57344
readv(258, […], 8) = 65536
readv(258, […], 7) = 57344
readv(258, […], 8) = 65536
readv(258, […], 7) = 57344
readv(258, […], 8) = 65536
pread(258, "624200202101231213*00014>277001000-410v213*0"..., 81920, 3162112) = 81920
pread(258, "624200214101231213*00014333177001000-410v213*0"..., 81920, 3244032) = 81920
pread(258, "624200226101231213*00010041264001000-410v213*0"..., 81920, 3325952) = 81920
pread(258, "624200240101231213*00024305u001000-410v213*0"..., 81920, 3407872) = 81920
pread(258, "624200252101231213*000240251001000-410v213*0"..., 81920, 3489792) = 81920
pread(258, "624200252101231213*000240251001000-410v213*0"..., 81920, 3489792) = 81920
readv(258, [{"624200276101231213*00024273-001000-410v213*0"..., 8192}, {"624200277101231213*000200
40223001000-410v213*0"..., 8192}, {"624200300101231213*00024331,001000-410v213*0"..., 8192}, {"6242
00301101231213*00024b235001000-410v213*0"..., 8192}, {"624200302101231213*00024u262001000-41
16
0v213*0"..., 8192}, {"624200303101231213*00024356H001000-410v213*0"..., 8192}, {"624200304101231213*
000242720001000-410v213*0"..., 8192}], 7) = 57344
The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey
What is the value of my DB_FILE_MULTIBLOCK_READ_COUNT parameter?
•

Was it set manually or by default by Oracle?

show parameter spfile
NAME
TYPE
VALUE
------ ------ ----------------------------------spfile string /u01/app/oracle/product/11.2.0
/dbhome_11203e/dbs/spfileorcle.ora

Instance started using spfile

show parameter db_file_multiblock_read_count
NAME
TYPE
VALUE
----------------------------- ------- ----db_file_multiblock_read_count integer 128

in pfile

SELECT nvl(value,‘MBRC param is NULL') AS value
FROM v$spparameter
WHERE name = 'db_file_multiblock_read_count';
VALUE
------------------------------------------MBRC param is NULL

MBRC parameter is set

not in spfile

SELECT value FROM v$parameter WHERE name = 'db_file_multiblock_read_count';
VALUE
----128

128 * 8k = 1Mb
17
The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey
Why does DBFMBRC parameter has such a low value?
show parameter db_file_multiblock_read_count
NAME
TYPE
VALUE
----------------------------- ------- ----db_file_multiblock_read_count integer 128
show parameter processes
NAME
TYPE
VALUE
----------------------------- ------- ----Processes
integer 150

db default setting

quite a difference due to

alter system set processes=8192 scope=spfile;
shutdown immediate;
startup;

processes difference

show parameter db_file_multiblock_read_count
NAME
TYPE
VALUE
----------------------------- ------- ----db_file_multiblock_read_count integer 7

18
The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey
I/O cost calculations: DBFMBRC parameter or MBRC system statistic?
WORKLOAD statistics available => MBRC
NOWORKLOAD statistics available
• if DBFMBRC parameter explicitly set => DBFMBRC
• if DBFMBRC parameter not explicitly set (is determined by db) => 8

19
I/O cost of multiblock read
Fairly common SETUP:
•
NOWORKLOAD statistics, db_block_size = 8k
•
db_file_multiblock_read_count set to 128 in spfile: ALTER SESSION SET db_file_multiblock_read_count = 128
* ensure MBRC comes from an explicit setting in parameter file, not from the automatically Oracle-computed one when MRBC is not explicitly set
10053 CBO Trace
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------SQL_ID 2w79jmd33myhm, child number 0
------------------------------------select * from people
Plan hash value: 2528372185
---------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)| Time
|
---------------------------------------------------------------------------|
0 | SELECT STATEMENT |
|
|
|
36 (100)|
|
|
1 | TABLE ACCESS FULL| PEOPLE | 10000 | 1240K|
36
(0)| 00:00:01 |
---------------------------------------------------------------------------delete plan_table;
explain plan for select * from people;
select io_cost, cpu_cost from plan_table where
id=1;
IO_COST CPU_COST
------- -------36 3902924
select blocks from user_tables where
table_name='PEOPLE';
BLOCKS
ceil ( blocks
-----197

Access path analysis for PEOPLE
***************************************
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for PEOPLE[PEOPLE]
Table: PEOPLE Alias: PEOPLE
Card: Original: 10000.000000 Rounded: 10000 Computed:
10000.00 Non Adjusted: 10000.00
Access Path: TableScan
Cost: 36.19 Resp: 36.19 Degree: 0
Cost_io: 36.00 Cost_cpu: 3902924
Resp_io: 36.00 Resp_cpu: 3902924
Best:: AccessPath: TableScan
Cost: 36.19 Degree: 1 Resp: 36.19 Card: 10000.00
Bytes: 0
***************************************
CPU cost transformed to number of single-block reads per second

cpu_cost/(cpuspeed*sredtim*1000)

COST = I/O cost + CPU cost

/ db_file_multiblock_read_count * mreadtim / sreadtim ) + 1
ioseektim + db_block_size/iotfrspeed
ioseektim + db_file_multiblock_read_count * db_block_size/iotfrspeed

select * from
SNAME
------------SYSSTATS_MAIN
SYSSTATS_MAIN
SYSSTATS_MAIN

sys.aux_stats$ where pname in ('CPUSPEEDNW', 'IOSEEKTIM', 'IOTFRSPEED');
PNAME
PVAL1 PVAL2
---------- ---------- ----CPUSPEEDNW 1751.75879
IOSEEKTIM
10
IOTFRSPEED
4096
CPU

sreadtim = 10 + 8192 / 4096 = 12
mreadtim = 10 + 128 * 8192 / 4096 = 266
IO cost = ceil (197 / 128 * 266 / 12) + 1 = 36
20
cost = (3902924/(1751.75879 * 12 * 1000)) = .185666924

* COST formula from Christian Antognini, after unsuccessfullly using the formula from Oracle 9i Performance Tuning Guide
I/O cost of table accesses based on index range scans
DB INITIALIZATION PARAMETERS

optimizer_index_caching
optimizer_index_cost_adj
((blevel + leaf_blocks * selectivity) * (1 -- ------------------------------------ ) + clustering_factor * selectivity ) * --------------------------------------100
100

LEAF_BLOCKS
DBA_IND_STATISTICS BLEVEL
CLUSTERING_FACTOR
DBA_IND_STATISTICS.DISTINCT_KEYS / DBA_IND_STATISTICS.DISTINCT_NUM_ROWS

How does this compare to the formula for I/O cost of multiblock reads?
* COST formula from Christian Antognini

21
THANK YOU!
22

Oracle Query Optimizer - An Introduction

  • 1.
    Adrian Buboi Senior OracleDBA, SCC Services Romania DBA Lounge Iasi: 17-10-2013
  • 2.
     Definition andevolution  Method  Object statistics  System statistics  Parameters used by the Optimizer  Cost calculation example 2
  • 3.
    • “The optimizeris built-in software that determines the most efficient way to execute a SQL statement.” - Oracle® Database Performance Tuning Guide 11g Release 2 (11.2) INPUTS SELECT /*+ FULL(T) */ T.* FROM Table T WHERE . . . OPTIMIZER With its mathematical model containing logic and default assumptions *already parsed by parser • Optimizer parameters EXECUTION PLAN • System statistics • Object statistics A C T I O N S (with the lowest estimated cost) • Performs query transformations (view merging, predicate pushing, subquery unnesting, query rewrite with MVs, etc) • Computes multiple possible execution plans together with their estimated cost 3
  • 4.
    • RBO =Rule Based Optimizer, predecessor of CBO • CBO = Cost Based Optimizer • RBO considered only the number of read requests, and used a set of predefined rules for deciding the best execution plan – these made it predictable and consistently produced the same execution plan • But, those fixed rules (e.g. single block read takes as much as multiblock, it is always better to use an index than to FTS) did not apply in plenty situations, so • CBO improved the situation, taking into account the size of read requests, time taken by read requests, CPU consumed, effect of caching • COST = the Optimizer estimated resource usage for a given plan; the lower the cost, the more efficient an execution plan is expected to be The beginning of Oracle database Oracle v7 Oracle v8i Oracle v9iR2 Oracle v10gR2 Oracle v11gR2 End of the 1970s 1992 1999 2002 2005 2009 1988 1997 2001 2003 2007 Oracle v6 Oracle v8 Oracle v9i Oracle v10g Oracle v11g Cardinality feedback Peace and quiet all around … or not? Bind variable peeking RBO de-supported CBO default Stored Outlines Advanced Cursor Sharing SQL Profiles 2013 Auto adjusted Dynamic Sampling Oracle v12c Adaptive Query Optimization Direct path reads for serial table scans SQL Plan Management – SQL Plan Baselines CBO - CPU costing RBO – IO costing 4 * What would you preffer: fixed plans performing consistently less-than-best-performant over time, or changing plans giving best performance together with less-than-best-performance?
  • 5.
    What is wrongwith the cost figure from execution plan? (sometimes, but enough times to make us go crazy!) Join Type Cost from Explain Plan Execution Time Nested Loop n HOURS Hash Join n x 100000 seconds * NO, the statement does NOT contain bind variables ** YES, the results are consistently repeatable, so no workload variation root cause *** Object statistics (histograms and extended statistics included) collected What could be the CBOs excuses? • Data statistics lie to CBO just enough to make him go south • CBO knows about the data just what object statistics tell him • System statistics lie to CBO just enough to make him go south • CBO knows about the underlying hardware just what system statistics tell him • Workload on the system at query execution time is not known when CBO computes the execution plan • One of the recent Oracle shots to alleviate the above is the new Oracle 12c feature - Adaptive Query Optimization • There is no such thing as perfect software , and CBO is no exception: it contains shortcomings, not-always-correct assumptions and bugs • Oracle tries to address the above with every new major release, patch set , 5 patch set update, one-off fixes, but they still keep coming!
  • 6.
    • Oracle 10053Event trace = generates a trace file containing Optimizer’s actions when generating an Execution Plan • Traced simple query: SELECT … FROM on Oracle 11.2.0.3 EE 64bit on top of Oracle Linux Server 6.3 DBMS_SYSTEM.SET_EV(si=>123, se=>1234, ev=>10053, le=>1, nm=>' '); ALTER SESSION SET events '10053 trace name context forever, level 1'; ALTER SESSION SET events 'trace[rdbms.SQL_Optimizer.*][sql:SQL_ID]'; • Sections of interest from the trace file: • Legend = abbreviations used by optimizer trace • Parameters used by the optimizer [including Bug Fix Control Environment] • Query Transformations • Peeked values of the binds in SQL statement • System statistics information • Base statistical information [Object statistics] • Access path analysis (includes Cost) • Optimizer statistics and computations [General Plans, Join Permutations, Execution Plan – includes Cost] 6
  • 7.
    New diagnostic eventsinfrastructure C /C++ module names which can be seen in OS stack traces of Oracle process (e.g. using SQL> oradebug doc component SQL_Compiler SQL_Compiler SQL Compiler ) SQL_Parser SQL Parser (qcs) SQL_Semantic SQL Semantic Analysis (kkm) SQL_Optimizer SQL Optimizer SQL_Transform SQL Transformation (kkq, vop, nso) SQL_MVRW SQL Materialized View Rewrite SQL_VMerge SQL View Merging (kkqvm) SQL_Virtual SQL Virtual Column (qksvc, kkfi) SQL_APA SQL Access Path Analysis (apa) SQL_Costing SQL Cost-based Analysis (kko, kke) SQL_Parallel_Optimization SQL Parallel Optimization (kkopq) SQL_Code_Generator SQL Code Generator (qka, qkn, qke, kkfd, qkx) SQL_Parallel_Compilation SQL Parallel Compilation (kkfd) SQL_Expression_Analysis SQL Expression Analysis (qke) SQL_Plan_Management SQL Plan Managment (kkopm) MPGE MPGE (qksctx) pstack 7
  • 8.
    • Describe thedatabase data • Types: table, column, index statistics • Besides user schemas objects, they can also be gathered against: • Oracle dictionary tables • Oracle fixed tables (which are in fact memory structures and not real tables) • DBMS_STATS is the tool to work with statistics • Oracle nightly statistics gathering default job – collects stats on tables with no / stale statistics • Does NOT collect fixed table statistics – these should be gathered manually • Besides gathered, statistics can be locked, compared, moved between databases, deleted • Can be manually set to desired values • Have configurable retention • Statistics operations performed at database/schema level are instrumented in DBA_OPSTAT_OPERATIONS 8
  • 9.
    Table statistics SELECT num_rows,blocks, avg_row_len, to_char(last_analyzed, 'dd.mm.yyyy hh24:mi') as last_analyzed, sample_size FROM USER_TABLES WHERE table_name = 'PEOPLE'; NUM_ROWS BLOCKS AVG_ROW_LEN LAST_ANALYZED SAMPLE_SIZE ---------- ---------- ----------- ---------------- ----------10000 197 127 15.10.2013 15:35 10000 • Should be kept relevant / up to date 9
  • 10.
    Column statistics SELECT column_name,num_distinct, low_value, high_value, density, num_nulls, avg_col_len, histogram, num_buckets, to_char(last_analyzed, 'dd.mm.yyyy hh24:mi') as last_analyzed, sample_size FROM USER_TAB_COL_STATISTICS WHERE table_name = 'PEOPLE'; COLUMN_NAME NUM_DISTINCT LOW_VALUE HIGH_VALUE DENSITY NUM_NULLS AVG_COL_LEN LAST_ANALYZED ----------- ------------ ------------ ------------------ ---------- --------- ----------- ---------------ID 10000 C102 C302 .0001 0 4 15.10.2013 19:06 NAME 9998 4E616D652030 4E616D652039393937 .00010002 0 10 15.10.2013 19:06 AGE 71 C102 C148 .014084507 0 3 15.10.2013 19:06 GENDER 2 46 4D .5 0 2 15.10.2013 19:06 CITY 10 436974792031 436974792039 .1 0 8 15.10.2013 19:06 Number between 0 and 1 With no histograms: 1/num_distinct With histograms: depend on histogram type Min and Max values in internal representation format Can be translated to human-readable values using utl_raw and dbms_stats.covert_raw_* procedures • Histograms • Extended statistics – object statistics about expressions and/or groups of columns 10
  • 11.
    Index statistics SELECT index_name,blevel, leaf_blocks, distinct_keys, num_rows, clustering_factor, avg_leaf_blocks_per_key, avg_data_blocks_per_key, to_char(last_analyzed, 'dd.mm.yyyy hh24:mi') as last_analyzed FROM user_ind_statistics WHERE table_name = 'PEOPLE'; INDEX_NAME BLEVEL LEAF_BLOCKS DISTINCT_KEYS NUM_ROWS CLUSTERING_FACTOR AVG_LEAF_BLOCKS_PER_KEY AVG_DATA_BLOCKS_PER_KEY LAST_ANALYZED ---------- ------ ----------- ------------- -------- ----------------- ----------------------- ----------------------- ---------------PK_PEOPLE 1 20 10000 10000 185 1 1 15.10.2013 19:37 Root block Branch block Leaf block Leaf block Leaf block Branch block Leaf block Leaf block Leaf block
  • 12.
    SELECT * FROMsys.aux_stats$; NOWORKLOAD statistics SNAME ------------SYSSTATS_INFO SYSSTATS_INFO SYSSTATS_INFO SYSSTATS_INFO SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN PNAME PVAL1 PVAL2 ---------- ---------- ---------------STATUS COMPLETED DSTART 09-17-2011 10:21 DSTOP 09-17-2011 10:21 FLAGS 1 CPUSPEEDNW 1751.75879 IOSEEKTIM 10 IOTFRSPEED 4096 SREADTIM MREADTIM CPUSPEED MBRC MAXTHR SLAVETHR • Always-available by default since 10g DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode=> noworkload’) • Oracle generates workload for both CPU and I/O benchmarks – so stats need to be gathered when the system is idle Millions of operations per second a CPU can process Average time (in milliseconds) to locate data on disk (default 10) Average number of bytes per millisecond that can be transferred from the disk (default 4096) Average time (in milliseconds) taken by a single block read Average time (in milliseconds) taken by a multiblock read Average number of blocks read during a multiblock read Maximum I/O throughput (bytes/s) of the system Possible approach: Gather system statistics for several days and either • Leave them in place, or • Manually set them to averages / max values computed from collected data dbms_stats.set_system_stats Average I/O throughput (bytes/s) of a parallel processing slave WORKLOAD statistics DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode interval => => => => ‘start’) ‘stop’) ‘interval’, 30) • Oracle does not generate workload for I/O benchmark – so stats need to be gathered during a representative workload I/O and CPU performance about the system Oracle engine runs on 12
  • 13.
    321 parameters inthe 10053 Optimizer trace file • 64 we can fiddle with on prod without asking Oracle Support • 257 hidden • • • • • • • • OPTIMIZER_MODE [default: ALL_ROWS; other values: first_rows_[1 | 10 | 100 | 1000] | first_rows] DB_FILE_MULTIBLOCK_READ_COUNT [see next slides] OPTIMIZER_DYNAMIC_SAMPLING [default value: 2; range of values: 0 - 10] OPTIMIZER_FEATURES_ENABLE [default value: 11.2.0.1; range of values: 8.0.0 … 11.2.0.1] QUERY_REWRITE_ENABLED [default: true] QUERY_REWRITE_INTEGRITY [default: enforced] STAR_TRANSFORMATION_ENABLED [default: false] PGA_AGGREGATE_TARGET (WORKAREA_SIZE_POLICY = AUTO) [default: MAX(10Mb, 20% of SGA size)] • BITMAP_MERGE_AREA_SIZE, HASH_AREA_SIZE , SORT_AREA_SIZE, SORT_AREA_RETAIN (WORKAREA_SIZE_POLICY = MANUAL) • OPTIMIZER_INDEX_CACHING [default: 0, range of values: 0 - 100] • OPTIMIZER_INDEX_COST_ADJ [default: 100, range of values: 1 - 10000] • PARALLEL_* 13
  • 14.
    The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey Officialdocumentation quotes: <q> DB_FILE_MULTIBLOCK_READ_COUNT is one of the parameters you can use to minimize I/O during table scans. It specifies the maximum number of blocks read in one I/O operation during a sequential scan. […] As of Oracle Database 10g release 2, the default value of this parameter is a value that corresponds to the maximum I/O size that can be performed efficiently. This value is platform-dependent and is 1MB for most platforms. […] Note that if the number of sessions is extremely large the multiblock read count value is decreased to avoid the buffer cache getting flooded with too many table scan buffers. […] Even though the default value may be a large value, the optimizer will not favor large plans if you do not set this parameter. It would do so only if you explicitly set this parameter to a large value. </q> Oracle® Database Reference 11g Release 2 (11.2) 14
  • 15.
    The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey DB_FILE_MULTIBLOCK_READ_COUNTdoes not always reads contiguous blocks! Why? • blocks in buffer cache (dirty or current, does not matter) are not read from I/O subsystem • physical multiblock reads do not cross extent boundaries • segment headers are read using single block reads ALTER SYSTEM SET db_file_multiblock_read_count = 10; alter session set tracefile_identifier='sql_trace_5'; exec dbms_monitor.session_trace_enable(waits => true); select * from people; exec dbms_monitor.session_trace_disable; WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT WAIT #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: #139960512564400: nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db nam='db file file file file file file file file file file file file file file file file file file file file file file file scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered scattered read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' read' ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= ela= 335 file#=4 block#=171 blocks=5 obj#=78893 tim=1381952652556960 58 file#=4 block#=176 blocks=8 obj#=78893 tim=1381952652560928 111 file#=4 block#=185 blocks=7 obj#=78893 tim=1381952652564213 197 file#=4 block#=192 blocks=8 obj#=78893 tim=1381952652567468 211 file#=4 block#=201 blocks=7 obj#=78893 tim=1381952652570871 714 file#=4 block#=208 blocks=8 obj#=78893 tim=1381952652574104 282 file#=4 block#=217 blocks=7 obj#=78893 tim=1381952652577456 261 file#=4 block#=224 blocks=8 obj#=78893 tim=1381952652580403 258 file#=4 block#=233 blocks=7 obj#=78893 tim=1381952653556908 129 file#=4 block#=240 blocks=8 obj#=78893 tim=1381952653561688 202 file#=4 block#=249 blocks=7 obj#=78893 tim=1381952653565008 149 file#=4 block#=256 blocks=8 obj#=78893 tim=1381952653567697 153 file#=4 block#=265 blocks=7 obj#=78893 tim=1381952653571069 112 file#=4 block#=272 blocks=8 obj#=78893 tim=1381952653573783 167 file#=4 block#=281 blocks=7 obj#=78893 tim=1381952653576354 325 file#=4 block#=288 blocks=8 obj#=78893 tim=1381952653579429 161 file#=4 block#=386 blocks=10 obj#=78893 tim=1381952654688751 41 file#=4 block#=396 blocks=10 obj#=78893 tim=1381952654692630 105 file#=4 block#=406 blocks=10 obj#=78893 tim=1381952654696428 104 file#=4 block#=416 blocks=10 obj#=78893 tim=1381952654699846 98 file#=4 block#=426 blocks=10 obj#=78893 tim=1381952654703829 155 file#=4 block#=436 blocks=10 obj#=78893 tim=1381952655808778 238 file#=4 block#=446 blocks=7 obj#=78893 tim=1381952655814160 15
  • 16.
    The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey FromOS strace –pPID readv(258, [{"624200253001~213*00024210223001000-410v213*0"..., 8192}, {"624200254001~213*00024k1001000-410v213*0"..., 8192}, {"624200255001~213*00024372323001000410v213*0"..., 8192}, {"624200256001~213*00024G.001000-410v213*0"..., 8192}, {"624200257001~213*00024272212001000-410v213*0"..., 8192}], 5) = 40960 readv(258, [{"624200260001~213*00024@=001000-410v213*0"..., 8192}, {"624200261001~213*00024315324001000-410v213*0"..., 8192}, {"624200262001~213*0002417722001000-410v213*0"..., 8192}, {"624200263001~213*00024214235001000-410v213*0"..., 8192}, {"624200264001~213*00024l25001000410v213*0"..., 8192}, {"624200265001~213*00020045W001000-410v213*0"..., 8192}, {"624200266001~213*00024235274001000-410v213*0"..., 8192}, {"624200267001~213*00024A9001000410v213*0"..., 8192}], 8) = 65536 readv(258, [{"624200271001200213*00024255352001000-410v213*0"..., 8192}, {"624200272001200213*00024~U001000-410v213*0"..., 8192}, {"624200273001200213*00024355263001000-410v213*0"..., 8192}, {"624200274001200213*00024[l001000-410v213*0"..., 8192}, {"624200275001200213*00024222310001000-410v213*0"..., 8192}, {"624200276001200213*00024Y364001000-410v213*0"..., 8192}, {"624200277001200213*000242720001000-410v213*0"..., 8192}], 7) = 57344 readv(258, […], 8) = 65536 readv(258, […], 7) = 57344 readv(258, […], 8) = 65536 readv(258, […], 7) = 57344 readv(258, […], 8) = 65536 readv(258, […], 7) = 57344 readv(258, […], 8) = 65536 readv(258, […], 7) = 57344 readv(258, […], 8) = 65536 readv(258, […], 7) = 57344 readv(258, […], 8) = 65536 readv(258, […], 7) = 57344 readv(258, […], 8) = 65536 pread(258, "624200202101231213*00014>277001000-410v213*0"..., 81920, 3162112) = 81920 pread(258, "624200214101231213*00014333177001000-410v213*0"..., 81920, 3244032) = 81920 pread(258, "624200226101231213*00010041264001000-410v213*0"..., 81920, 3325952) = 81920 pread(258, "624200240101231213*00024305u001000-410v213*0"..., 81920, 3407872) = 81920 pread(258, "624200252101231213*000240251001000-410v213*0"..., 81920, 3489792) = 81920 pread(258, "624200252101231213*000240251001000-410v213*0"..., 81920, 3489792) = 81920 readv(258, [{"624200276101231213*00024273-001000-410v213*0"..., 8192}, {"624200277101231213*000200 40223001000-410v213*0"..., 8192}, {"624200300101231213*00024331,001000-410v213*0"..., 8192}, {"6242 00301101231213*00024b235001000-410v213*0"..., 8192}, {"624200302101231213*00024u262001000-41 16 0v213*0"..., 8192}, {"624200303101231213*00024356H001000-410v213*0"..., 8192}, {"624200304101231213* 000242720001000-410v213*0"..., 8192}], 7) = 57344
  • 17.
    The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey Whatis the value of my DB_FILE_MULTIBLOCK_READ_COUNT parameter? • Was it set manually or by default by Oracle? show parameter spfile NAME TYPE VALUE ------ ------ ----------------------------------spfile string /u01/app/oracle/product/11.2.0 /dbhome_11203e/dbs/spfileorcle.ora Instance started using spfile show parameter db_file_multiblock_read_count NAME TYPE VALUE ----------------------------- ------- ----db_file_multiblock_read_count integer 128 in pfile SELECT nvl(value,‘MBRC param is NULL') AS value FROM v$spparameter WHERE name = 'db_file_multiblock_read_count'; VALUE ------------------------------------------MBRC param is NULL MBRC parameter is set not in spfile SELECT value FROM v$parameter WHERE name = 'db_file_multiblock_read_count'; VALUE ----128 128 * 8k = 1Mb 17
  • 18.
    The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey Whydoes DBFMBRC parameter has such a low value? show parameter db_file_multiblock_read_count NAME TYPE VALUE ----------------------------- ------- ----db_file_multiblock_read_count integer 128 show parameter processes NAME TYPE VALUE ----------------------------- ------- ----Processes integer 150 db default setting quite a difference due to alter system set processes=8192 scope=spfile; shutdown immediate; startup; processes difference show parameter db_file_multiblock_read_count NAME TYPE VALUE ----------------------------- ------- ----db_file_multiblock_read_count integer 7 18
  • 19.
    The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey I/Ocost calculations: DBFMBRC parameter or MBRC system statistic? WORKLOAD statistics available => MBRC NOWORKLOAD statistics available • if DBFMBRC parameter explicitly set => DBFMBRC • if DBFMBRC parameter not explicitly set (is determined by db) => 8 19
  • 20.
    I/O cost ofmultiblock read Fairly common SETUP: • NOWORKLOAD statistics, db_block_size = 8k • db_file_multiblock_read_count set to 128 in spfile: ALTER SESSION SET db_file_multiblock_read_count = 128 * ensure MBRC comes from an explicit setting in parameter file, not from the automatically Oracle-computed one when MRBC is not explicitly set 10053 CBO Trace PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------SQL_ID 2w79jmd33myhm, child number 0 ------------------------------------select * from people Plan hash value: 2528372185 ---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | 36 (100)| | | 1 | TABLE ACCESS FULL| PEOPLE | 10000 | 1240K| 36 (0)| 00:00:01 | ---------------------------------------------------------------------------delete plan_table; explain plan for select * from people; select io_cost, cpu_cost from plan_table where id=1; IO_COST CPU_COST ------- -------36 3902924 select blocks from user_tables where table_name='PEOPLE'; BLOCKS ceil ( blocks -----197 Access path analysis for PEOPLE *************************************** SINGLE TABLE ACCESS PATH Single Table Cardinality Estimation for PEOPLE[PEOPLE] Table: PEOPLE Alias: PEOPLE Card: Original: 10000.000000 Rounded: 10000 Computed: 10000.00 Non Adjusted: 10000.00 Access Path: TableScan Cost: 36.19 Resp: 36.19 Degree: 0 Cost_io: 36.00 Cost_cpu: 3902924 Resp_io: 36.00 Resp_cpu: 3902924 Best:: AccessPath: TableScan Cost: 36.19 Degree: 1 Resp: 36.19 Card: 10000.00 Bytes: 0 *************************************** CPU cost transformed to number of single-block reads per second cpu_cost/(cpuspeed*sredtim*1000) COST = I/O cost + CPU cost / db_file_multiblock_read_count * mreadtim / sreadtim ) + 1 ioseektim + db_block_size/iotfrspeed ioseektim + db_file_multiblock_read_count * db_block_size/iotfrspeed select * from SNAME ------------SYSSTATS_MAIN SYSSTATS_MAIN SYSSTATS_MAIN sys.aux_stats$ where pname in ('CPUSPEEDNW', 'IOSEEKTIM', 'IOTFRSPEED'); PNAME PVAL1 PVAL2 ---------- ---------- ----CPUSPEEDNW 1751.75879 IOSEEKTIM 10 IOTFRSPEED 4096 CPU sreadtim = 10 + 8192 / 4096 = 12 mreadtim = 10 + 128 * 8192 / 4096 = 266 IO cost = ceil (197 / 128 * 266 / 12) + 1 = 36 20 cost = (3902924/(1751.75879 * 12 * 1000)) = .185666924 * COST formula from Christian Antognini, after unsuccessfullly using the formula from Oracle 9i Performance Tuning Guide
  • 21.
    I/O cost oftable accesses based on index range scans DB INITIALIZATION PARAMETERS optimizer_index_caching optimizer_index_cost_adj ((blevel + leaf_blocks * selectivity) * (1 -- ------------------------------------ ) + clustering_factor * selectivity ) * --------------------------------------100 100 LEAF_BLOCKS DBA_IND_STATISTICS BLEVEL CLUSTERING_FACTOR DBA_IND_STATISTICS.DISTINCT_KEYS / DBA_IND_STATISTICS.DISTINCT_NUM_ROWS How does this compare to the formula for I/O cost of multiblock reads? * COST formula from Christian Antognini 21
  • 22.

Editor's Notes

  • #4 An Optimizer-like piece of software is needed at runtime because SQL is a declarative (high level) language, so someone has to translate those statements into low level steps to be performedEfficient = The query fed to Optimizer is already parsed by ParserThe query hints are also an input of OptimizerView merging = view definition is merged into the containing query blockPredicate pushing = predicates from query are pushed into the referenced view definitionSubqueryunnesting = nested subqueries are transformed in equivalent join statements with the parent query block
  • #5 The Optimizer chooses the best plan based on a cost it assigns to each candidate plan it computes – hence it is said to be cost based (CBO)Even in 11.2 you still might get to use RBO: there are Oracle internal SELECTs (e.g. when calling DBMS_STATS.GATHER_TABLE_STATS with certain parameters) which contain the RULE hint – which is obeyed if all the necessary conditions are met (mainly no CBO-supported-only new features applying to involved tables); you can even use RULE hint, which might be obeyed in certain situations