In 9i: selectivty of index(col1, col2, col3)= density (co11) x denisty (col2) x denisity(col3);
In 10g and 11g selectivity of index(col1, col2, col3) = 1/DISTINCT_KEYS where DISTINCT_KEYS is from index stats obtainable through dba_indexes.
Here is the test case which mimics the production able and the problem sql.
----- begin of the test case ----
drop table test;
create table test
as
select level id,
trunc(mod(level,80)) id1,
20*trunc(mod(level, 40)) id2,
1 id3,
trunc(mod(level,50)) id4
from dual
connect by level <=1000000;
create index test_ix1 on test(id1, id2, id3);
exec dbms_stats.gather_table_stats(user,'test', method_opt=>'FOR ALL COLUMNS size 1', cascade=>true);
alter session set tracefile_identifier = test;
ALTER SESSION SET EVENTS='10053 trace name context forever, level 1';
explain plan for
select id
from test
where id1 = 20
and id3=1
and id2 = 400;
ALTER SESSION SET EVENTS '10053 trace name context off';
Exit
------ end of test case -----------------------
#### 9.2.0.8 10053 trace excerpt
***************************************
SINGLE TABLE ACCESS PATH
Column: ID1 Col#: 2 Table: TEST Alias: TEST
NDV: 80 NULLS: 0 DENS: 1.2500e-02 LO: 0 HI: 79
NO HISTOGRAM: #BKT: 1 #VAL: 2
Column: ID3 Col#: 4 Table: TEST Alias: TEST
NDV: 1 NULLS: 0 DENS: 1.0000e+00 LO: 1 HI: 1
NO HISTOGRAM: #BKT: 1 #VAL: 2
Column: ID2 Col#: 3 Table: TEST Alias: TEST
NDV: 40 NULLS: 0 DENS: 2.5000e-02 LO: 0 HI: 780
NO HISTOGRAM: #BKT: 1 #VAL: 2
TABLE: TEST ORIG CDN: 1000000 ROUNDED CDN: 313 CMPTD CDN: 313
Access path: tsc Resc: 857 Resp: 847
Access path: index (equal)
Index: TEST_IX1
TABLE: TEST
RSC_CPU: 711380 RSC_IO: 82
IX_SEL: 0.0000e+00 TB_SEL: 3.1250e-04
BEST_CST: 83.00 PATH: 4 Degree: 1
#### 10.2.0.4 10053 trace excerpt
***************************************
SINGLE TABLE ACCESS PATH
-----------------------------------------
BEGIN Single Table Cardinality Estimation
-----------------------------------------
Column (#2): ID1(NUMBER)
AvgLen: 3.00 NDV: 81 Nulls: 0 Density: 0.012346 Min: 0 Max: 79
Column (#4): ID3(NUMBER)
AvgLen: 3.00 NDV: 1 Nulls: 0 Density: 1 Min: 1 Max: 1
Column (#3): ID2(NUMBER)
AvgLen: 4.00 NDV: 40 Nulls: 0 Density: 0.025 Min: 0 Max: 780
Table: TEST Alias: TEST
Card: Original: 1003092 Rounded: 310 Computed: 309.60 Non Adjusted: 309.60
-----------------------------------------
END Single Table Cardinality Estimation
-----------------------------------------
Access Path: TableScan
Cost: 730.88 Resp: 730.88 Degree: 0
Cost_io: 700.00 Cost_cpu: 284170229
Resp_io: 700.00 Resp_cpu: 284170229
Access Path: index (AllEqRange)
Index: TEST_IX1
resc_io: 3173.00 resc_cpu: 27721329
ix_sel: 0.0125 ix_sel_with_filters: 0.0125
Cost: 3176.01 Resp: 3176.01 Degree: 1
Best:: AccessPath: TableScan
Cost: 730.88 Degree: 1 Resp: 730.88 Card: 309.60 Bytes: 0
Note:
select index_name, distinct_keys from user_indexes where index_name='TEST_IX1';
INDEX_NAME DISTINCT_KEYS
------------------------------ -------------
TEST_IX1 80
#### 11.2.0.1 10053 trace excerpt
***************************************
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for TEST[TEST]
ColGroup (#1, Index) TEST_IX1
Col#: 2 3 4 CorStregth: 40.00
ColGroup Usage:: PredCnt: 3 Matches Full: #1 Partial: Sel: 0.0125
Table: TEST Alias: TEST
Card: Original: 1000000.000000 Rounded: 12500 Computed: 12500.00 Non Adjusted: 12500.00
Access Path: TableScan
Cost: 629.80 Resp: 629.80 Degree: 0
Cost_io: 617.00 Cost_cpu: 283372261
Resp_io: 617.00 Resp_cpu: 283372261
ColGroup Usage:: PredCnt: 3 Matches Full: #1 Partial: Sel: 0.0125
ColGroup Usage:: PredCnt: 3 Matches Full: #1 Partial: Sel: 0.0125
Access Path: index (AllEqRange)
Index: TEST_IX1
resc_io: 3173.00 resc_cpu: 27721329
ix_sel: 0.012500 ix_sel_with_filters: 0.012500
Cost: 3174.25 Resp: 3174.25 Degree: 1
Best:: AccessPath: TableScan
Cost: 629.80 Degree: 1 Resp: 629.80 Card: 12500.00 Bytes: 0
Notice the ix_sel line in the above 10053 trace excerpt; for 10g and 11g it equal to 1/80. for 9i seems computed through multiplying selectivity of eeach column.
Update:
Came accross Jonathan Lewis's comment, and came to know this CBO behavior changes acctually from 10.1.0.4 ie. 10.1.0.4 is still similar to 9i behavior.
Below is his comment: (http://kr.forums.oracle.com/forums/thread.jspa?messageID=3153224)
--------
For a single-table query with the predicate
(full list of index columns) = (set of values)
The selectivities vary across version as follows:
11.1.0.6: Table selectivity and index selectivity given by distinct_keys in index
10.2.0.1: Table selectivity given by product of column selectivities, index selectivity given by distinct_keys in index
10.1.0.4: Table selectivity and index selectivity given by product of column selectivities
------------
JL's original post about this behavior: http://jonathanlewis.wordpress.com/2008/03/11/everything-changes/