Sem,
I did not understand your sentence "The declared rule of thumb to use index is 95/5, so after 20 days B-tree index becomes usefull." could you explain ? What do you mean by (95/5) ?
As I personnaly use a lot of bitmap indexes in my DWH, I wanted to verify what I said on bitmap indexes:
Please test the following!
-- Create a table (n,dt1,dt2) with test values
create table testbitmaps
as (select rownum as n, trunc(sysdate,'D')-5+mod(rownum,30) as dt1, -- values for 1 month
trunc(sysdate,'D')+mod(rownum,1095) as dt2 --values for 3 years
from all_tab_columns);
-- create 2 bitmaps
create bitmap index idt1 on testbitmaps(dt1);
create bitmap index idt2 on testbitmaps(dt2);
-- analyze all
analyze table testbitmaps compute statistics;
-- how many values
select count

,count(distinct dt1), count(distinct dt2) from testbitmaps;
-- I got
-- COUNT(N) COUNT(DISTINCTDT1) COUNT(DISTINCTDT2)
------------ ------------------ ------------------
-- 18344 30 1095
-- then do some tests:
set autotrace traceonly exp
Then tests:
*** Between ***
SQL> select * from testbitmaps where sysdate between dt1 and dt2;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=7331 Bytes=13
1958)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TESTBITMAPS' (Cost=5 Car
d=7331 Bytes=131958)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP INDEX (RANGE SCAN) OF 'IDT1'
*** Operations ****
SQL> select * from testbitmaps where sysdate+25>dt1-3
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=9 Card=918 Bytes=165
24)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TESTBITMAPS' (Cost=9 Car
d=918 Bytes=16524)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP INDEX (FULL SCAN) OF 'IDT1'
**** count(*) ****
SQL> select count(*) from testbitmaps where sysdate between dt1 and dt2;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=14)
1 0 SORT (AGGREGATE)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP AND
4 3 BITMAP MERGE
5 4 BITMAP INDEX (RANGE SCAN) OF 'IDT1'
6 3 BITMAP MERGE
7 6 BITMAP INDEX (RANGE SCAN) OF 'IDT2'
*** equal ***
SQL> select * from testbitmaps where trunc(sysdate)=dt2;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=17 Bytes=306)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TESTBITMAPS' (Cost=1 Car
d=17 Bytes=306)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP INDEX (SINGLE VALUE) OF 'IDT2'
SQL> select * from testbitmaps where trunc(sysdate)=dt2 or trunc(sysdate)=dt1;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=628 Bytes=113
04)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TESTBITMAPS' (Cost=4 Car
d=628 Bytes=11304)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP OR
4 3 BITMAP INDEX (SINGLE VALUE) OF 'IDT2'
5 3 BITMAP INDEX (SINGLE VALUE) OF 'IDT1'