Is the INLIST ITERATOR unable to use the index unless we specify NOT NULL? I wanted to
bounce this off the list before we log a TAR.
We are examining the performance of a query and I am trying to understand why an
INLIST ITERATOR is not used if there is not an explicit IS NOT NULL predicate
condition.
TableA.column1 is nullable, has null values and has a high number of distinct values.
It also has a nonunique index with only column1.
The table and indexes are recently analyzed. The column has a histogram with 2 buckets.
In the query, the predicate for column1 is "where column1 in ('<value1>',
'<value2>')". Both of the values are literals and actual values do exist in the table.
If we use just this predicate (along with the other join conditions), the execution
plan is a series of hash joins on full table scans (cost of 38756/card of 3). If we
add "and column1 is not null", the execution plan is an INLIST ITERATOR with a series
of nested loops using index range or unique scans.
In looking at a 10053 trace file, it becomes clear as to why the query is taking a bad
plan. The cost of a single table access is radically different.
With Not Null (Note the tb_sel values (which seem to be the density * # of values) are
correct in this computation)
SINGLE TABLE ACCESS PATH
TABLE: SERIALS ORIG CDN: 3318658 ROUNDED CDN: 2 CMPTD CDN: 2
Access path: tsc Resc: 7137 Resp: 7137
Access path: index (no sta/stp keys)
Index: SERIALS_MAN_SER
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 19877
IX_SEL: 1.0000e+00 TB_SEL: 6.0265e-07
Access path: index (scan)
Index: SERIALS_SER
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 5
IX_SEL: 6.0277e-07 TB_SEL: 6.0265e-07
Access path: index (equal)
Index: SERIALS_SER
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 3
IX_SEL: 3.0138e-07 TB_SEL: 3.0133e-07
Access path: index (equal)
Index: SERIALS_SER
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 3
IX_SEL: 3.0138e-07 TB_SEL: 3.0133e-07
BEST_CST: 5.00 PATH: 4 Degree: 1
Without Not Null (Note the tb_sel values are not correct. If I read this correctly,
this is telling the CBO that there is a single value for each of the index columns)
SINGLE TABLE ACCESS PATH
TABLE: SERIALS ORIG CDN: 3318658 ROUNDED CDN: 3318658 CMPTD CDN: 3318658
Access path: tsc Resc: 7137 Resp: 7137
Access path: index (no sta/stp keys)
Index: SERIALS_EQ
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 13265
IX_SEL: 1.0000e+00 TB_SEL: 1.0000e+00
Access path: index (no sta/stp keys)
Index: SERIALS_MAN_SER
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 19875
IX_SEL: 1.0000e+00 TB_SEL: 1.0000e+00
Access path: index (no sta/stp keys)
Index: SERIALS_SER
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 12155
IX_SEL: 1.0000e+00 TB_SEL: 1.0000e+00
Access path: index (no sta/stp keys)
Index: SERIALS_UC
TABLE: SERIALS
RSC_CPU: 0 RSC_IO: 7361
IX_SEL: 1.0000e+00 TB_SEL: 1.0000e+00
BEST_CST: 7137.00 PATH: 2 Degree: 1
The interesting thing is if I extract the access of this table to a single
(non-joined) statement, it computes the cost and plan like I would expect. It is when
we add in other tables and a join condition that it 'loses' its mind.
Thoughts? Need More Detail?
begin:vcard
n:Fink;Daniel
tel;cell:303.808.3282
tel;work:303.272.3225
x-mozilla-html:TRUE
adr:;;;;;;
version:2.1
email;internet:[EMAIL PROTECTED]
title:DB Services Lead
x-mozilla-cpt:;-4832
fn:Daniel Fink
end:vcard