oracle query optimizer - an introduction

22
Oracle Query Optimizer An Introduction Adrian Buboi Senior Oracle DBA, SCC Services Romania DBA Lounge Iasi: 17-10-2013

Upload: adryanbub

Post on 25-May-2015

705 views

Category:

Technology


6 download

DESCRIPTION

An attempt to present Oracle Query Optimizer concepts together with some related saucy details / real-life situations.

TRANSCRIPT

Page 1: Oracle Query Optimizer - An Introduction

Oracle Query

OptimizerAn Introduction

Adrian BuboiSenior Oracle DBA, SCC Services RomaniaDBA Lounge Iasi: 17-10-2013

Page 2: Oracle Query Optimizer - An Introduction

2

Definition and evolution

Method

Object statistics

System statistics

Parameters used by the Optimizer

Cost calculation example

Agenda

Page 3: Oracle Query Optimizer - An Introduction

3

Definition and evolution

• “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)

SELECT /*+ FULL(T) */ T.* FROM Table TWHERE . . .*already parsed by parser

OPTIMIZERWith its mathematical model containing logic and default assumptions

• Optimizer parameters• System statistics• Object statistics

• Performs query transformations (view merging, predicate pushing, subquery unnesting, query rewrite with MVs, etc)• Computes multiple possible execution plans together with their estimated cost

I N P U T S

A C T I O N S

EXECUTIONPLAN

(with the lowest estimated cost)

PRODUCES

Page 4: Oracle Query Optimizer - An Introduction

4

Definition and evolution

• 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

End of the 1970s

1988

Oracle v6

Oracle v7

1992

1997

Oracle v8

Oracle v8i

1999

2001

Oracle v9i

Oracle v9iR2

2002

2003

Oracle v10g

Oracle v10gR2

2005

2007

Oracle v11g

2013

Oracle v12c

Oracle v11gR2

2009

RBO de-supportedCBO default

CBO - CPU costing

Adaptive QueryOptimization

RBO – IO costing

Advanced Cursor Sharing

SQL Plan Management – SQL Plan BaselinesStored Outlines SQL Profiles

Bind variable peeking

Auto adjusted Dynamic Sampling

Direct path reads for serial table scans

Peace and quiet all around … or not?

ORACLE OPTIMIZER EVOLUTIONwith an emphasis on execution plan stability (non)features

Cardinality feedback

* 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?

Page 5: Oracle Query Optimizer - An Introduction

5

Definition and evolution

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 , patch set update, one-off fixes, but they still keep coming!

Page 6: Oracle Query Optimizer - An Introduction

6

Method

• 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]

Page 7: Oracle Query Optimizer - An Introduction

7

Method

New diagnostic events infrastructure

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)

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

pstack)

Page 8: Oracle Query Optimizer - An Introduction

8

Object statistics

• 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

Page 9: Oracle Query Optimizer - An Introduction

9

Object statistics

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

Page 10: Oracle Query Optimizer - An Introduction

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:06NAME 9998 4E616D652030 4E616D652039393937 .00010002 0 10 15.10.2013 19:06AGE 71 C102 C148 .014084507 0 3 15.10.2013 19:06GENDER 2 46 4D .5 0 2 15.10.2013 19:06CITY 10 436974792031 436974792039 .1 0 8 15.10.2013 19:06

Object statistics

Min and Max values in internal representation format

Can be translated to human-readable values using utl_raw and dbms_stats.covert_raw_* procedures

Number between 0 and 1With no histograms: 1/num_distinct With histograms: depend on histogram type

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

Page 11: Oracle Query Optimizer - An Introduction

Object statistics

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 Branch block

Leaf block Leaf blockLeaf blockLeaf blockLeaf blockLeaf block

Page 12: Oracle Query Optimizer - An Introduction

12

System statistics

SELECT * FROM sys.aux_stats$;

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

NOWORKLOAD statistics• Always-available by default since 10gDBMS_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

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

WORKLOAD statisticsDBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode => ‘start’)DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode => ‘stop’)DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode => ‘interval’,

interval => 30)

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

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 datadbms_stats.set_system_stats

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

Page 13: Oracle Query Optimizer - An Introduction

13

Parameters used by the Optimizer

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_*

Page 14: Oracle Query Optimizer - An Introduction

14

Parameters used by the Optimizer

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)

Page 15: Oracle Query Optimizer - An Introduction

15

Parameters used by the Optimizer

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

Page 16: Oracle Query Optimizer - An Introduction

16

Parameters used by the Optimizer

The DB_FILE_MULTIBLOCK_READ_COUNT OdysseyFrom OS

strace –pPID

readv(258, [{"\6\242\0\0\253\0\0\1~\213*\0\0\0\2\4\210\223\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\254\0\0\1~\213*\0\0\0\2\4k1\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\255\0\0\1~\213*\0\0\0\2\4\372\323\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\256\0\0\1~\213*\0\0\0\2\4G.\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\257\0\0\1~\213*\0\0\0\2\4\272\212\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}], 5) = 40960readv(258, [{"\6\242\0\0\260\0\0\1~\213*\0\0\0\2\4@=\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\261\0\0\1~\213*\0\0\0\2\4\315\324\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\262\0\0\1~\213*\0\0\0\2\4\177\22\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\263\0\0\1~\213*\0\0\0\2\4\214\235\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\264\0\0\1~\213*\0\0\0\2\4l\25\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\265\0\0\1~\213*\0\0\0\2\0045W\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\266\0\0\1~\213*\0\0\0\2\4\235\274\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\267\0\0\1~\213*\0\0\0\2\4A9\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}], 8) = 65536readv(258, [{"\6\242\0\0\271\0\0\1\200\213*\0\0\0\2\4\255\352\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\272\0\0\1\200\213*\0\0\0\2\4~U\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\273\0\0\1\200\213*\0\0\0\2\4\355\263\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\274\0\0\1\200\213*\0\0\0\2\4[l\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\275\0\0\1\200\213*\0\0\0\2\4\222\310\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\276\0\0\1\200\213*\0\0\0\2\4Y\364\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\277\0\0\1\200\213*\0\0\0\2\4\2720\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}], 7) = 57344readv(258, […], 8) = 65536readv(258, […], 7) = 57344readv(258, […], 8) = 65536readv(258, […], 7) = 57344readv(258, […], 8) = 65536readv(258, […], 7) = 57344readv(258, […], 8) = 65536readv(258, […], 7) = 57344readv(258, […], 8) = 65536readv(258, […], 7) = 57344readv(258, […], 8) = 65536readv(258, […], 7) = 57344readv(258, […], 8) = 65536pread(258, "\6\242\0\0\202\1\0\1\231\213*\0\0\0\1\4>\277\0\0\1\0\0\0-4\1\0v\213*\0"..., 81920, 3162112) = 81920pread(258, "\6\242\0\0\214\1\0\1\231\213*\0\0\0\1\4\333\177\0\0\1\0\0\0-4\1\0v\213*\0"..., 81920, 3244032) = 81920pread(258, "\6\242\0\0\226\1\0\1\231\213*\0\0\0\1\0041\264\0\0\1\0\0\0-4\1\0v\213*\0"..., 81920, 3325952) = 81920pread(258, "\6\242\0\0\240\1\0\1\231\213*\0\0\0\2\4\305u\0\0\1\0\0\0-4\1\0v\213*\0"..., 81920, 3407872) = 81920pread(258, "\6\242\0\0\252\1\0\1\231\213*\0\0\0\2\4\0\251\0\0\1\0\0\0-4\1\0v\213*\0"..., 81920, 3489792) = 81920pread(258, "\6\242\0\0\252\1\0\1\231\213*\0\0\0\2\4\0\251\0\0\1\0\0\0-4\1\0v\213*\0"..., 81920, 3489792) = 81920readv(258, [{"\6\242\0\0\276\1\0\1\231\213*\0\0\0\2\4\273-\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\277\1\0\1\231\213*\0\0\0\2\00 40\223\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\300\1\0\1\231\213*\0\0\0\2\4\331,\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\ 0\0\301\1\0\1\231\213*\0\0\0\2\4b\235\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\302\1\0\1\231\213*\0\0\0\2\4u\262\0\0\1\0\0\0-4\1\ 0v\213*\0"..., 8192}, {"\6\242\0\0\303\1\0\1\231\213*\0\0\0\2\4\356H\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}, {"\6\242\0\0\304\1\0\1\231\213*\ 0\0\0\2\4\27\20\0\0\1\0\0\0-4\1\0v\213*\0"..., 8192}], 7) = 57344

Page 17: Oracle Query Optimizer - An Introduction

17

Parameters used by the Optimizer

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 spfileNAME TYPE VALUE------ ------ -----------------------------------spfile string /u01/app/oracle/product/11.2.0 /dbhome_11203e/dbs/spfileorcle.ora

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

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

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

Instance started using spfile

MBRC parameter is set

in pfile

not in spfile

128 * 8k = 1Mb

Page 18: Oracle Query Optimizer - An Introduction

18

Parameters used by the Optimizer

The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey

Why does DBFMBRC parameter has such a low value?

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

show parameter processesNAME TYPE VALUE----------------------------- ------- -----Processes integer 150

alter system set processes=8192 scope=spfile;

shutdown immediate;startup;

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

db default setting

quite a difference due to

processes difference

Page 19: Oracle Query Optimizer - An Introduction

19

Parameters used by the Optimizer

The DB_FILE_MULTIBLOCK_READ_COUNT Odyssey

I/O cost calculations: DBFMBRC parameter or MBRC system statistic?

WORKLOAD statistics available => MBRCNOWORKLOAD statistics available• if DBFMBRC parameter explicitly set => DBFMBRC• if DBFMBRC parameter not explicitly set (is determined by db) => 8

Page 20: Oracle Query Optimizer - An Introduction

20

Cost calculation example

I/O cost of multiblock readFairly 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

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 |----------------------------------------------------------------------------

10053 CBO TraceAccess 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/(cpuspeed*sredtim*1000)

COST = I/O cost + CPU costceil ( blocks / db_file_multiblock_read_count * mreadtim / sreadtim ) + 1

ioseektim + db_block_size/iotfrspeed

ioseektim + db_file_multiblock_read_count * db_block_size/iotfrspeed

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------ 197

CPU cost transformed to number of single-block reads per second

select * from sys.aux_stats$ where pname in ('CPUSPEEDNW', 'IOSEEKTIM', 'IOTFRSPEED');SNAME PNAME PVAL1 PVAL2------------- ---------- ---------- -----SYSSTATS_MAIN CPUSPEEDNW 1751.75879  SYSSTATS_MAIN IOSEEKTIM 10  SYSSTATS_MAIN IOTFRSPEED 4096

sreadtim = 10 + 8192 / 4096 = 12mreadtim = 10 + 128 * 8192 / 4096 = 266

IO cost = ceil (197 / 128 * 266 / 12) + 1 = 36CPU cost = (3902924/(1751.75879 * 12 * 1000)) = .185666924

* COST formula from Christian Antognini, after unsuccessfullly using the formula from Oracle 9i Performance Tuning Guide

Page 21: Oracle Query Optimizer - An Introduction

21

Cost calculation example

I/O cost of table accesses based on index range scans

* COST formula from Christian Antognini

How does this compare to the formula for I/O cost of multiblock reads?

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

LEAF_BLOCKSDBA_IND_STATISTICS BLEVEL CLUSTERING_FACTOR

DB INITIALIZATION PARAMETERS

DBA_IND_STATISTICS.DISTINCT_KEYS / DBA_IND_STATISTICS.DISTINCT_NUM_ROWS

Page 22: Oracle Query Optimizer - An Introduction

22

THANK YOU!