um mit Sicherheit sagen zu können, was sich der cost based optimizer da denkt, bräuchte man den
execution plan der Query, aber Folgendes dürfte zutreffen:
Ein bitmap Index ist in der Regel deutlich kleiner als ein B*Tree-Index (weil ein bitmap Index - abhänig von der Clusterung der zugehörigen Werte in der Tabelle - relativ gut komprimiert werden kann).
Um die Anzahl der Sätze in der Tabelle zu ermitteln, kann der Optimizer einen INDEX FAST FULL SCAN auf einem verwendbaren Index durchführen, wobei in diesem Fall jeder Index für eine Spalte, die als NOT NULL definiert worden ist, verwendet werden kann (Spalten, die NULL-Werte enthalten, kommen nicht in Frage, da bei einspaltigen Indizes NULL-Werte nicht indiziert werden - und deshalb würde die Anzahl der Leaf-Elemente im Index nicht der Anzahl der Sätze der Tabelle entsprechen).
Für diesen INDEX FAST FULL SCAN wird der cbo den kleinsten verfügbaren Index benutzen.
Dazu ein kleiner Test:
Code:
-- Anlage einer Testtabelle mit zwei Spalten
create table test1
(col1 number(10) not null,
col2 number(10));
-- Füllung mit fast 1.000.000 Sätzen
insert into test1
select rownum col1
, mod(rownum, 100) col2
from dual
connect by level < 1000000
-- Anlage eines PK
alter table test1 add constraint test1_pk primary key (col1);
-- Anlage eines zweiten Index auf der Spalte col2, die NULL-Werte enthalten darf
create index test1_idx1 on test1(col2);
-- Ermittlung von Statistiken
exec dbms_stats.gather_table_stats(user, 'TEST1')
-- Die Größe der Indizes
select table_name
, index_name
, LEAF_BLOCKS
from user_indexes
where table_name like 'TEST%';
TABLE_NAME INDEX_NAME LEAF_BLOCKS
------------------------------ ------------------------------ -----------
TEST1 TEST1_PK 1030
TEST1 TEST1_IDX1 962
Wie vermutet, ist der bitmap Index kleiner als der B*Tee-Index des PK. Jetzt die Testquery:
Code:
select count(*) from TEST1;
-- und der von autotrace gelieferte Plan:
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 37 (38)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| TEST1_PK | 1012K| 37 (38)| 00:00:01 |
--------------------------------------------------------------------------
Statistiken
----------------------------------------------------------
1 recursive calls
0 db block gets
1041 consistent gets
0 physical reads
0 redo size
344 bytes sent via SQL*Net to client
338 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Der cbo verwendet hier den Index des Primary Keys, obwohl der Bitmap Index (in diesem Fall nur geringfügig) kleiner ist. Wenn ich jetzt aber die Spalte col2 als NOT NULL definiere, ändert der cbo seine Meinung:
Code:
-- NOT NULL für col2
alter table TEST1 modify col2 not null;
-- Query
select count(*) from TEST1;
-- Autotrace:
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 35 (40)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| TEST1_IDX1 | 1012K| 35 (40)| 00:00:01 |
----------------------------------------------------------------------------
Statistiken
----------------------------------------------------------
0 recursive calls
0 db block gets
971 consistent gets
0 physical reads
0 redo size
344 bytes sent via SQL*Net to client
338 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
In diesem Test ist der Unterschied nicht groß (971 statt 1041 Blockzugriffe), aber oft sind bitmap Indizes deutlich kleiner als B*Tree-Indizes, und dann ist der bitmap Index deutlich effektiver.
Im Netz findet man eine sehr interessante Präsentation von Julian Dyke, die Details zu den technischen Details der bitmap Indizes und ihrer Arbeitsweise liefert (der Link findet sich am Ende eines
Blog-Eintrags, den ich damit auch noch hier unterbringe...
Nachtrag: sehr viel Wissenswertes zu bitmap (und B*Tree) Indizes findet man auch in Richard Footes (englischsprachigem)
Blog
Gruß
MP