An article on 10053 Trace Files - Global Stats on Partitioned Tables by Doug Burns is a good introduction to my problem. Doug has included excerpts from the 10053 trace covering a few variations, but one that appears incomplete is the case where there are:
- Global stats
- No partition-level stats
- Single partition being queried
- IN-LIST Query
In this situation I have a few differing results
This is what I don't want, a block count of 1, as that means a full table scan is always going to be better than an index scan. A full table scan is perfectly fine *if* there is actually only 1 block, but there's actually whole lot more - the optimizer got it wrong. Worse, good old bind variable peeking means that this peeked full table scan plan will also get used on partitions that contain lots of data.
***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
Table: INVOICE Alias: INVOICE (Using composite stats)
(making adjustments for partition skews)
ORIGINAL VALUES:: #Rows: 343372313 #Blks: 8296936 AvgRowLen: 142.00
PARTITIONS::
PRUNED: 1
ANALYZED: 0 UNANALYZED: 1
#Rows: 343372313 #Blks: 1 AvgRowLen: 142.00
I have a test table with 3 partitions (two large, one small), a locally partitioned index on the partitioning key, and global stats. Then I query the small partition with
SELECT * FROM test WHERE id in (2000001, 2000002)
Variation 1 (as above): The optimizer adjusts to use 1 block.
Variation 3: If I create the test table with a NOT NULL partitioning key, the optimizer adjusts to use 1 block.
I haven't been able to work out how why variation 2 is different. This is the result I want ALWAYS.
Peter.