Why Isn't Oracle Using My Index?
Why Isn't Oracle Using My Index?
The question in the title of this piece is probably the single most frequently occurring
question that appears in the Metalink forums and Usenet newsgroups. This article
uses a test case that you can rebuild on your own systems to demonstrate the most
fundamental issues with how cost-based optimisation works. And at the end of the
article, you should be much better equipped to give an answer the next time you
hear that dreaded question.
All the rows with the value 45 do you will find that our two tables each
actually appear one after the other in a cover 96 blocks.
tight little clump (probably all fitting one
data block) in the table. At the start of the article, I pointed out
that the test case was running a
Table T2 uses the mod() function to version 8 system with the value 8 for
generate the N1 values, using the db_file_multiblock_read_count.
modulus 200 on the rownum:
Roughly speaking, Oracle has decided
mod(45,200) = 45 that it can read the entire 96 block
mod(245,200) = 45 table in 96/8 = 12 disk read requests.
…
mod(2845,200) = 45 Since it takes 16 block (= disk read)
requests to access the table by index,
The rows with the value 45 appear it is clearer quicker (from Oracle's
every two hundredth position in the sadly deluded perspective) to scan the
table (probably resulting in no more table - after all 12 is less than 16.
than one row in every relevant block).
Voila ! If the data you are targetting is
By doing the analyze, Oracle was able suitably scattered across the table, you
to get a perfect description of the data get tablescans even for a very small
scatter in our table. So the optimiser percentage of the data - a problem that
was able to work out exactly how can be exaggerated in the case of very
many blocks Oracle would have to visit big blocks and very small rows.
to answer our query - and, in simple
cases, the number of block visits is the Correction
cost of the query. In fact you will have noticed that my
calculated number of scan reads was
But why the tablescan ? 12, whilst the cost reported in the
So we see that an indexed access into execution plan was 15. It is a slight
T2 is more expensive than the same simplfication to say that the cost of a
path into T1, but why has Oracle tablescan (or an index fast full scan for
switched to the tablescan ? that matter) is