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