Dienstag, Mai 24, 2011

Insert Performance mit Bitmap- und B*Tree-Indizes

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