【基礎篇索引】索引基礎(三)

yellowlee發表於2010-07-10

索引型別

Btree索引和bitmap索引

Btree索引前面已經介紹到了,是oracle通用的索引,在葉塊儲存鍵值和rowid,在大區間內的查詢能夠取得非常好的效能,且資料插入,更新,刪除的效率較高,易於維護鍵值的順序,因此廣泛用於oltp系統中。在olap中的一些表,擁有很大的記錄數,基本不會做dml修改,且對於某個欄位來說卻只有很少的值,查詢中要使用到這個欄位,bitmap就是專為這種情況而設計的。建立一個表和bitmap索引來具體測試看看:

SQL> show parameters STAR_TRANSFORMATION_ENABLED

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ---------------------

star_transformation_enabled          string      FALSE

SQL> create table t_test_bitmap as select * from dba_objects;

 

表已建立。

 

SQL> desc dba_objects

 名稱                                      是否為空? 型別

 ----------------------------------------- -------- ------------------

 

 OWNER                                              VARCHAR2(30)

 OBJECT_NAME                                        VARCHAR2(128)

 SUBOBJECT_NAME                                     VARCHAR2(30)

 OBJECT_ID                                          NUMBER

 DATA_OBJECT_ID                                     NUMBER

 OBJECT_TYPE                                        VARCHAR2(19)

 CREATED                                            DATE

 LAST_DDL_TIME                                      DATE

 TIMESTAMP                                          VARCHAR2(19)

 STATUS                                             VARCHAR2(7)

 TEMPORARY                                          VARCHAR2(1)

 GENERATED                                          VARCHAR2(1)

 SECONDARY                                          VARCHAR2(1)

 

SQL> update t_test_bitmap set wner = 'TEST' where rownum < 10000;

 

已更新9999行。

 

SQL> update t_test_bitmap set wner = 'SYS' where owner !='TEST';

 

已更新39837行。

 

SQL> commit;

 

提交完成。

 

SQL> create bitmap index ind_bit_map_t1 on t_test_bitmap(owner);

 

索引已建立。

 

SQL>

 

SQL> select count(*) from t_test_bitmap where wner='TEST' ;

 

  COUNT(*)

----------

     19770

 

 

執行計劃

----------------------------------------------------------

Plan hash value: 42697208

 

--------------------------------------------------------------------------------

 

--------------

 

| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CP

 

U)| Time     |

 

--------------------------------------------------------------------------------

 

--------------

 

|   0 | SELECT STATEMENT            |                |     1 |    17 |     1   (

 

0)| 00:00:01 |

 

|   1 |  SORT AGGREGATE             |                |     1 |    17 |

  |          |

 

|   2 |   BITMAP CONVERSION COUNT   |                | 17978 |   298K|     1   (

 

0)| 00:00:01 |

 

|*  3 |    BITMAP INDEX SINGLE VALUE| IND_BIT_MAP_T1 |       |       |

  |          |

 

--------------------------------------------------------------------------------

 

--------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   3 - access("OWNER"='TEST')

 

Note

-----

   - dynamic sampling used for this statement

 

 

統計資訊

----------------------------------------------------------

          9  recursive calls

          0  db block gets

         80  consistent gets

          1  physical reads

          0  redo size

        410  bytes sent via SQL*Net to client

        385  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

上述黑體部分說明了查詢使用了bitmap索引,下面來看看bitmap的結構:

SQL> select a.index_name, a.index_type,

  2         a.blevel, a.leaf_blocks, a.distinct_keys

  3    from dba_indexes a

  4   where a.index_type = 'BITMAP';

 

INDEX_NAME            INDEX_TYPE       BLEVEL   LEAF_BLOCKS DISTINCT_KEYS

--------------------- -------------- ---------- ------- -------------

IND_BIT_MAP_T1        BITMAP                  1       2             2

 

SQL>

SQL> select a.header_file,a.header_block,a.bytes,a.extents,a.segment_name

  2   from dba_segments a

  3  where a.segment_name = 'IND_BIT_MAP_T1';

 

HEADER_FILE HEADER_BLOCK      BYTES    EXTENTS SEGMENT_NAME

----------- ------------ ---------- ---------- -------------------------

          1        80193      65536          1 IND_BIT_MAP_T1

 

SQL>

可以dump出來具體看看:

SQL> alter system dump datafile 1 block min 80193 block max 80201;

 

系統已更改。

 

下面是dump 出來的部分bitmap index block內容:

*** 2010-07-10 20:00:33.937

Start dump data blocks tsn: 0 file#: 1 minblk 80193 maxblk 80201

buffer tsn: 0 rdba: 0x00413941 (1/80193)

scn: 0x0000.0026798a seq: 0x01 flg: 0x04 tail: 0x798a1001

frmt: 0x02 chkval: 0x2831 type: 0x10=DATA SEGMENT HEADER – UNLIMITED

..

.

.

Branch block dump

=================

header address 181412420=0xad02244

kdxcolev 1

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y

kdxconco 4

kdxcosdc 0

kdxconro 1

kdxcofbo 30=0x1e

kdxcofeo 8053=0x1f75

kdxcoavs 8023

kdxbrlmc 4274499=0x413943

kdxbrsno 0

kdxbrbksz 8060

kdxbr2urrc 10

row#0[8053] dba: 4274500=0x413944

col 0; len 1; (1):  54

col 1; TERM

----- end of branch block dump -----

.

.

Leaf block dump

===============

header address 181412444=0xad0225c

kdxcolev 0

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y

kdxconco 4

kdxcosdc 0

kdxconro 2

kdxcofbo 40=0x28

kdxcofeo 1145=0x479

kdxcoavs 1105

kdxlespl 0

kdxlende 0

kdxlenxt 4274500=0x413944

kdxleprv 0=0x0

kdxledsz 0

kdxlebksz 8036

row#0[4499] flag: ------, lock: 0, len=3537

col 0; len 3; (3):  53 59 53

col 1; len 6; (6):  00 41 39 3e 00 20

col 2; len 6; (6):  00 41 3a a9 00 3f

col 3; len 3515; (3515):.

………

……

或者使用treedump看看bitmap的大致結構:

*** 2010-07-10 19:48:19.828

----- begin tree dump

branch: 0x413942 4274498 (0: nrow: 2, level: 1)

   leaf: 0x413943 4274499 (-1: nrow: 2 rrow: 2)

   leaf: 0x413944 4274500 (0: nrow: 1 rrow: 1)

----- end tree dump

可以看到bitmap依然是樹狀結構,每個葉子節點上只有一條記錄,對應的表資料記錄的地址則是通過國對映函式轉換得來。

 

Btree唯一索引和非唯一索引

顯然唯一索引的每個鍵值對應唯一的rowid,而非唯一索引可能對應多個,相比來說唯一索引的查詢效率更高。

 

函式索引

Functional based index 在一些情況下也比較有用,比如經常需要對某個或幾個欄位的計算值來做查詢,雖然很多時候也可以直接增加計算結果欄位的方式來處理,使用函式索引也是比較方便的,不用修改表結構。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16179598/viewspace-667724/,如需轉載,請註明出處,否則將追究法律責任。

相關文章