SQL> create table test1 2 as 3 select rownum col1 4 , trunc(rownum/10) col2 5 , trunc(rownum/100) col3 6 , trunc(rownum/1000) col4 7 , trunc(rownum/10000) col5 8 , trunc(rownum/100000) col6 9 from dual 10 connect by level <= 1000000; Tabelle wurde erstellt. SQL> create bitmap index test1_bidx2 on test1(col2); Index wurde erstellt. SQL> create bitmap index test1_bidx3 on test1(col3); Index wurde erstellt. SQL> select col2, col3 2 from test1 3 where col2 = 10; 10 Zeilen ausgewõhlt. Abgelaufen: 00:00:00.16 Ausf³hrungsplan ---------------------------------------------------------- Plan hash value: 724021477 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 10 | 260 | |* 1 | VIEW | index$_join$_001 | 10 | 260 | |* 2 | HASH JOIN | | | | | 3 | BITMAP CONVERSION TO ROWIDS| | 10 | 260 | |* 4 | BITMAP INDEX SINGLE VALUE | TEST1_BIDX2 | | | | 5 | BITMAP CONVERSION TO ROWIDS| | 10 | 260 | | 6 | BITMAP INDEX FULL SCAN | TEST1_BIDX3 | | | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("COL2"=10) 2 - access(ROWID=ROWID) 4 - access("COL2"=10) Note ----- - dynamic sampling used for this statement Statistiken ---------------------------------------------------------- 0 recursive calls 0 db block gets 31 consistent gets 0 physical reads 0 redo size 554 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 10 rows processed
Der Zugriff erfolgt in diesem Fall komplett über die beiden Indizes, die alle Informationen enthalten, so dass der Tabellenzugriff entfällt. Die Index-Informationen müssen allerdings über eine BITMAP CONVERSION TO ROWIDS umgewandelt werden.
Jetzt der Versuch mit einem Bitmap Index über zwei Spalten:
SQL> select col2, col3 2 from test1 3 where col2 = 10; 10 Zeilen ausgewõhlt. Abgelaufen: 00:00:00.02 Ausf³hrungsplan -------------------------------------------------------- Plan hash value: 3301052306 -------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | -------------------------------------------------------- | 0 | SELECT STATEMENT | | 22 | 572 | |* 1 | INDEX RANGE SCAN| TEST1_BIDX4 | 22 | 572 | -------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("COL2"=10) Note ----- - dynamic sampling used for this statement Statistiken -------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 554 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 10 rows processed
In diesem Fall genügt ein einfacher INDEX RANGE SCAN ohne weitere Konvertierung und der Zugriff wird billiger (4 statt 31 consistent gets; ohne die Indizes sind es 1970 consistent gets).Ein mehrspaltiger Index hat hier also durchaus Vorteile.
Keine Kommentare:
Kommentar veröffentlichen