Vielleicht habe ich mir die Frage schon früher gestellt, vielleicht auch schon beantwortet, vielleicht auch schon hier in diesem Blog - aber was soll's: zur Not eben eine Doublette. Ich gehe davon aus, dass Bitmap Indizes die Insert-Performance stärker beeinträchtigen als B*Tree Indizes (völlig abgesehen von locking, concurrency etc.). Dazu folgender Test (unter 11.2.0.1; EE; Noarchivelog):
drop table test;
create table test
( id number
, col1 number
, col2 number
, pad varchar2(64));
/*
create bitmap index test_col1 on test(col1);
create bitmap index test_col2 on test(col2);
*/
create index test_col1 on test(col1);
create index test_col2 on test(col2);
@ trace
insert /* btree */ into test
select rownum id
, mod(rownum, 40) col1
, round(rownum)/1000 col2
, lpad('*', 40, '*')
from dual
connect by level <= 1000000;
@ trace_end
Tatsächlich benötigt das Insert im Fall der B*Tree-Indizes 34 sec und im Fall der Bitmap-Indizes 67 sec. Hier die Details:
-- B*Tree
insert /* btree */ into test
select rownum id
, mod(rownum, 40) col1
, round(rownum)/1000 col2
, lpad('*', 40, '*')
from dual
connect by level <= 1000000
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.00 0 0 0 0
Execute 1 10.81 34.01 0 30292 2993170 1000000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 10.82 34.01 0 30292 2993170 1000000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 77
Rows Row Source Operation
------- ---------------------------------------------------
0 LOAD TABLE CONVENTIONAL (cr=0 pr=0 pw=0 time=0 us)
1 COUNT (cr=0 pr=0 pw=0 time=0 us)
1 CONNECT BY WITHOUT FILTERING (cr=0 pr=0 pw=0 time=0 us)
1 FAST DUAL (cr=0 pr=0 pw=0 time=0 us cost=2 size=0 card=1)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
Disk file operations I/O 15 0.48 1.28
log file switch completion 18 1.81 9.33
log buffer space 87 0.31 5.66
reliable message 83 0.00 0.00
rdbms ipc reply 87 1.02 1.67
control file sequential read 84 0.27 1.38
db file sequential read 8 0.01 0.05
Data file init write 4 0.00 0.00
db file single write 4 0.00 0.01
control file parallel write 12 0.00 0.02
enq: CF - contention 2 0.50 0.52
log file sync 1 0.08 0.08
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
-- Bitmap
insert /* bitmap */ into test
select rownum id
, mod(rownum, 40) col1
, round(rownum)/1000 col2
, lpad('*', 40, '*')
from dual
connect by level <= 1000000
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 29.10 67.64 0 5759962 5992713 1000000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 29.10 67.64 0 5759962 5992713 1000000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 77
Rows Row Source Operation
------- ---------------------------------------------------
0 LOAD TABLE CONVENTIONAL (cr=0 pr=0 pw=0 time=0 us)
1 COUNT (cr=0 pr=0 pw=0 time=0 us)
1 CONNECT BY WITHOUT FILTERING (cr=0 pr=0 pw=0 time=0 us)
1 FAST DUAL (cr=0 pr=0 pw=0 time=0 us cost=2 size=0 card=1)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
Disk file operations I/O 102 0.29 6.17
log file switch completion 26 0.10 1.13
control file sequential read 693 0.45 7.43
db file sequential read 66 0.07 0.62
Data file init write 33 0.00 0.00
db file single write 33 0.00 0.04
control file parallel write 99 0.08 0.48
rdbms ipc reply 33 0.15 0.59
log buffer space 44 0.27 2.24
latch: object queue header operation 1 0.00 0.00
enq: CF - contention 5 0.26 0.36
log file switch (checkpoint incomplete) 12 2.10 9.48
log file sync 1 0.03 0.03
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
Man sieht hier zum einen, dass mein Windows7-Rechner mit dem Logging leicht überfordert ist. Darüber hinaus kann man beobachten, dass die CPU-Last für die Bitmap-Indizes deutlich höher ist, und dass für diesen Fall sehr viel mehr LIOs (current gets und consistent gets) erscheinen. Aus v$sesstat geht hervor, dass der Bitmap-Fall deutlich weniger Arbeitsspeicher nutzt (PGA, UGA), und dass er mehr undo und redo hervorruft (was möglicherweise auch mit dem Noarchivelog-Modus zusammenhängt. Sehr viele der consistent gets fallen übrigens in die Kategorie "
consistent gets - examination" (und sollten demnach relativ flott sein). Auch in anderen Statistiken zeigt der Bitmap-Fall deutlich höhere Werte, aber ich bleibe erst mal bei der Beobachtung stehen, dass die Maintainance für Bitmap Indizes teurer ist, als für B*Tree Indizes.
Keine Kommentare:
Kommentar veröffentlichen