詳解oracle bitmap位圖索引

zt http://f.dataguru.cn/thread-226223-1-2.htmlhtml

位圖索引是oracle中很是重要的一種索引形式。本文經過總結有關位圖索引的資料,嘗試回答以下幾個問題:sql

1:什麼是位圖索引?數據庫

2:位圖索引適合什麼場景,不適合什麼場景?併發

3:位圖索引的性能如何?oracle


什麼是位圖索引?app

位圖索引,顧名思義,與「位」有關。你們都知道,計算機中的全部信息最終都是經過「位bit」來運算的, 二進制位運算在計算機中是很是高效的。每個二進制位均可以取值0或者1,而取值的確切含義是由具體的上下文環境決定的。在oracle位圖索引中,每個二進制位表明了某一行中索引列的取值狀況。例如,學生表中性別列的位圖索引結構以下:dom

男:0101001101ide

女:1010110010oop

在上面的位圖結構中,存儲了10條學生記錄的性別分佈狀況,以「男」性別爲例,從左到右的第n個二進制位表明了第n條記錄是否性別爲男,若是二進制位爲1,表明true即性別爲男,0表明false即性別不爲男。以此類推,從圖中能夠看出,第一條記錄的性別爲女,第二條記錄的性別爲男,...第九條記錄的性別爲女,第十條記錄的性別爲男。性能

你們都知道,在oracle中是根據rowid來定位記錄的,所以,咱們須要引入start rowid和end rowid,經過start rowid ,end rowid 和二進制位的偏移,咱們就能夠很是快速的計算出二進制位所表明的表記錄rowid。位圖索引的最終邏輯結構以下圖:


位圖索引適合什麼場景,不適合什麼場景?如今咱們已經瞭解了位圖索引的邏輯結構,咱們稱每一單元的<key ,startrowid,end rowid,bitmap>爲一個位圖片斷。當咱們修改某一行數據的時候,咱們須要鎖定該行列值所對應的位圖片斷,若是咱們進行的是更新操做,同時還會鎖定更新後新值所在的位圖片斷。例如咱們將列值從01修改成03,就須要同時鎖定01和03位圖片斷,此時若是有其餘用戶須要修改與01或者03關聯的表記錄上的索引字段,就會被阻塞,所以位圖索引不適合併發環境,在併發環境下可能會形成大量事務的阻塞。

從位圖索引的邏輯結構也能夠看出,當索引列的distinct cardinality較大時,索引所佔用的存儲空間也會成比例擴大。下面咱們測試一下位圖索引佔用空間與distinct cardinality的關係:
數據庫環境:oracle 11g  
數據塊大小:8k
[sql] view plaincopyprint?


  • CREATE or replace FUNCTION ind_spc_test(rn NUMBER) RETURN NUMBER  
  •   AS  
  •       v_j     NUMBER;  
  •       v_dis   NUMBER;  
  •       v_bm_sp NUMBER;  
  •       v_bt_sp NUMBER;  
  •     BEGIN  
  •       FOR i IN 1 .. 10LOOP  
  •         EXECUTE immediate 'truncate table t_easy1';  
  •         EXECUTE immediate 'truncate table t_easy2';  
  •         SELECT floor(rn/(11-i)) INTO v_j FROM dual;  
  •         FOR j IN 1 .. rn LOOP  
  •           INSERT INTO t_easy1 VALUES (mod(j,v_j));  
  •           INSERT INTO t_easy2 VALUES (mod(j,v_j));  
  •         END LOOP;  
  •         commit;  
  •         select count(distinct id) into v_j from t_easy1;  
  •         EXECUTE immediate 'analyze index i_easy1 COMPUTE STATISTICS';  
  •         SELECT lEAF_BLOCKS INTO v_bt_sp FROM user_indexes where index_name='I_EASY1';  
  •         EXECUTE immediate 'analyze index i_easy2 COMPUTE STATISTICS';  
  •         SELECT LEAF_BLOCKS INTO v_bm_sp FROM user_indexes where index_name='I_EASY2';  
  •         INSERT INTO bitmap_ind_space VALUES (v_j,v_bm_sp,v_bt_sp,rn );  
  •         COMMIT;  
  •       END LOOP;  
  •       RETURN 0;  
  •     END;  



[sql] view plaincopyprint?


  • SQL> select * from bitmap_ind_space order by 1;  
  •   
  • DISTINCT_VAL BITMAP_IND_BLKS BTREE_IND_BLKS    ROW_NUM  
  • ------------ --------------- -------------- ----------  
  •        10000         139        300 100000  
  •        11111          79        335 100000  
  •        12500          89        285 100000  
  •        14285         103        220 100000  
  •        16666         120        257 100000  
  •        20000         146        310 100000  
  •        25000         183        293 100000  
  •        33333         246        262 100000  
  •        50000         371        296 100000  
  •       100000         408        200 100000  



這裏的測試比較簡單,下面看看大師的實驗結果:




從這裏能夠看出,隨着distinct columns值的增長,位圖索引佔用空間逐步增大,但即使在最壞的狀況下,位圖索引佔用的空間也僅僅是普通索引的2~3倍,在存儲日益廣泛的今天,這恐怕並非很大的問題。

位圖索引的查詢性能如何?下面咱們看一下位圖索引的查詢性能如何。
在不少資料中,均可以看到這樣的論述:位圖索引適合於 low distict cardinality的列。實際上,對於high distinct cardinality 的列,位圖索引的查詢性能也是很是不錯的。下面咱們來驗證這個結論。
首先咱們建立兩張表:emp_normal和emp_random.
[sql] view plaincopyprint?


  • SQL> create table emp_normal(empno number(10), ename varchar2(30), sal number(10));  
  •   
  • 表已建立。  
  •   
  • Begin  
  • For i in 1..1000000  
  • Loop  
  •    Insert into emp_normal   
  •    values(i, dbms_random.string('U',30), dbms_random.value(1000,7000));  
  •    If mod(i, 10000) = 0 then  
  •    Commit;  
  •   End if;  
  • End loop;  
  • 10  End;  
  • 11  /  
  •   
  • PL/SQL 過程已成功完成。  
  •   
  • SQL> create table emp_random as select /* +append */ * from emp_normal order by dbms_random.random;  


emp_random因爲其記錄是隨機分佈的,所以該表上索引的CLUSTERING_FACTOR要高一些。
咱們首先看一下emp_normal表等值查詢狀況下,索引的效率如何:
[sql] view plaincopyprint?


  • SQL> create bitmap index bm_normal on emp_normal(empno);  
  •   
  • 索引已建立。  
  •   
  •   
  • SQL> analyze table emp_normal compute statistics for table for all indexes for all indexed columns;  
  •   
  • 表已分析。  
  •   
  • SQL> select index_name,clustering_factor from user_indexes;  
  •   
  • INDEX_NAME             CLUSTERING_FACTOR  
  • ------------------------------ -----------------  
  • BM_NORMAL                1000000  
  •   
  • SQL> set autot traceonly  
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  1000  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=1000  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 1526426521  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX SINGLE VALUE | BM_NORMAL  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO"=1000)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     702  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  
  •   
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  2398  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=2398  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 1526426521  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX SINGLE VALUE | BM_NORMAL  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO"=2398)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     703  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  
  •   
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  8545  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=8545  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 1526426521  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX SINGLE VALUE | BM_NORMAL  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO"=8545)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     703  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  
  •   
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  128444  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=128444  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 1526426521  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 |    34 | 3   (0)| 00:00:01 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX SINGLE VALUE | BM_NORMAL  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO"=128444)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     704  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  
  •   
  • SQL> drop index bm_normal;  
  •   
  • 索引已刪除。  
  •   
  • SQL> create index bt_normal on emp_normal(empno);  
  •   
  • 索引已建立。  
  •   
  • SQL> analyze table emp_normal compute statistics for table for all indexes for all indexed columns;  
  •   
  • 表已分析。  
  •   
  • SQL> select index_name,clustering_factor from user_indexes;  
  •   
  • INDEX_NAME             CLUSTERING_FACTOR  
  • ------------------------------ -----------------  
  • BT_NORMAL                   6210  
  • SYS_IL0000076897C00002$$  
  • PK_EMP                         1  
  • PK_DEPT                        1  
  •   
  • SQL> set autot traceonly  
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  1000  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=1000  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 733975378  
  •   
  • ------------------------------------------------------------------------------------------  
  • | Id  | Operation           | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • ------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT        |        |     1 |    34 |     4   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID| EMP_NORMAL |     1 |    34 |     4   (0)| 00:00:01 |  
  • |*  2 |   INDEX RANGE SCAN      | BT_NORMAL  |     1 |   |     3   (0)| 00:00:01 |  
  • ------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    2 - access("EMPNO"=1000)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     702  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  
  •   
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  128444  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=128444  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 733975378  
  •   
  • ------------------------------------------------------------------------------------------  
  • | Id  | Operation           | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • ------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT        |        |     1 |    34 |     4   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID| EMP_NORMAL |     1 |    34 |     4   (0)| 00:00:01 |  
  • |*  2 |   INDEX RANGE SCAN      | BT_NORMAL  |     1 |   |     3   (0)| 00:00:01 |  
  • ------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    2 - access("EMPNO"=128444)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     704  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  
  •   
  • SQL> select * from emp_normal where empno=&empno;  
  • 輸入 empno 的值:  2398  
  • 原值    1: select * from emp_normal where empno=&empno  
  • 新值    1: select * from emp_normal where empno=2398  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 733975378  
  •   
  • ------------------------------------------------------------------------------------------  
  • | Id  | Operation           | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • ------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT        |        |     1 |    34 |     4   (0)| 00:00:01 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID| EMP_NORMAL |     1 |    34 |     4   (0)| 00:00:01 |  
  • |*  2 |   INDEX RANGE SCAN      | BT_NORMAL  |     1 |   |     3   (0)| 00:00:01 |  
  • ------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    2 - access("EMPNO"=2398)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •       5  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •     703  bytes sent via SQL*Net to client  
  •     520  bytes received via SQL*Net from client  
  •       2  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •       1  rows processed  


總結以下:

BITMAP EMPNO B-TREE
Consistent Reads Physical Reads Consistent Reads Physical Reads
5 0 1000 5 0
5 0 2398 5 0
5 0 8545 5 0
5 0 98008 5 0
5 0 85342 5 0
5 0 128444 5 0
5 0 858 5 0

對emp_random表進行實驗,得出的結果與之相似,這裏再也不獒述。從這裏能夠看出,在惟一列上的等值查詢,位圖索引與btree索引的效率至關。
下面,咱們在針對範圍查詢來進行測試。

[sql] view plaincopyprint?


  • SQL> create bitmap index bm_random  on emp_random(empno);  
  •   
  • 索引已建立。  
  •   
  • SQL> analyze table emp_random compute statistics for table for all indexes for all columns;  
  •   
  • 表已分析。  
  •   
  • SQL> select index_name,clustering_factor from user_indexes;  
  •   
  • INDEX_NAME             CLUSTERING_FACTOR  
  • ------------------------------ -----------------  
  • BM_RANDOM                1000000  
  •   
  •   
  • SQL> set autot traceonly  
  • SQL> select * from emp_random where empno between &range1 and &range2;  
  • 輸入 range1 的值:  1  
  • 輸入 range2 的值:  2300  
  • 原值    1: select * from emp_random where empno between &range1 and &range2  
  • 新值    1: select * from emp_random where empno between 1 and 2300  
  •   
  • 已選擇2300行。  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 811843605  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        |  2299 | 85063 |   418   (1)| 00:00:06 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_RANDOM |  2299 | 85063 |   418   (1)| 00:00:06 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX RANGE SCAN   | BM_RANDOM  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO">=1 AND "EMPNO"<=2300)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •        2463  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •      130225  bytes sent via SQL*Net to client  
  •        2203  bytes received via SQL*Net from client  
  •     155  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •        2300  rows processed  
  •   
  • SQL> select * from emp_random where empno between &range1 and &range2;  
  • 輸入 range1 的值:  8  
  • 輸入 range2 的值:  1980  
  • 原值    1: select * from emp_random where empno between &range1 and &range2  
  • 新值    1: select * from emp_random where empno between 8 and 1980  
  •   
  • 已選擇1973行。  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 811843605  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        |  1972 | 72964 |   366   (0)| 00:00:05 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_RANDOM |  1972 | 72964 |   366   (0)| 00:00:05 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX RANGE SCAN   | BM_RANDOM  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO">=8 AND "EMPNO"<=1980)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •        2114  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •      111758  bytes sent via SQL*Net to client  
  •        1961  bytes received via SQL*Net from client  
  •     133  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •        1973  rows processed  
  •   
  • SQL> select * from emp_random where empno between &range1 and &range2;  
  • 輸入 range1 的值:  28888  
  • 輸入 range2 的值:  31850  
  • 原值    1: select * from emp_random where empno between &range1 and &range2  
  • 新值    1: select * from emp_random where empno between 28888 and 31850  
  •   
  • 已選擇2963行。  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 811843605  
  •   
  • -------------------------------------------------------------------------------------------  
  • | Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |  
  • -------------------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT         |        |  2962 |   107K|   513   (0)| 00:00:07 |  
  • |   1 |  TABLE ACCESS BY INDEX ROWID | EMP_RANDOM |  2962 |   107K|   513   (0)| 00:00:07 |  
  • |   2 |   BITMAP CONVERSION TO ROWIDS|        |   |   |        |      |  
  • |*  3 |    BITMAP INDEX RANGE SCAN   | BM_RANDOM  |   |   |        |      |  
  • -------------------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    3 - access("EMPNO">=28888 AND "EMPNO"<=31850)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •        3172  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •      170625  bytes sent via SQL*Net to client  
  •        2687  bytes received via SQL*Net from client  
  •     199  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •        2963  rows processed  
  •   
  • SQL> drop index bm_random;  
  •   
  • 索引已刪除。  
  •   
  • SQL> create index bt_random on emp_random(empno);  
  •   
  • 索引已建立。  
  •   
  • SQL> analyze table emp_random compute statistics for table for all indexes for all columns;  
  •   
  • 表已分析。  
  •   
  • SQL> set autot off  
  • SQL> select index_name,clustering_factor from user_indexes;  
  •   
  • INDEX_NAME             CLUSTERING_FACTOR  
  • ------------------------------ -----------------  
  • BT_RANDOM                 999834  
  • SQL> set autot traceonly  
  • SQL> select * from emp_random where empno between &range1 and &range2;  
  • 輸入 range1 的值:  1  
  • 輸入 range2 的值:  2300  
  • 原值    1: select * from emp_random where empno between &range1 and &range2  
  • 新值    1: select * from emp_random where empno between 1 and 2300  
  •   
  • 已選擇2300行。  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 731629521  
  •   
  • --------------------------------------------------------------------------------  
  • | Id  | Operation     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |  
  • --------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT  |        |  2299 | 85063 |  1735   (1)| 00:00:21 |  
  • |*  1 |  TABLE ACCESS FULL| EMP_RANDOM |  2299 | 85063 |  1735   (1)| 00:00:21 |  
  • --------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    1 - filter("EMPNO"<=2300 AND "EMPNO">=1)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •        6410  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •      121081  bytes sent via SQL*Net to client  
  •        2203  bytes received via SQL*Net from client  
  •     155  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •        2300  rows processed  
  •   
  • SQL> select * from emp_random where empno between &range1 and &range2;  
  • 輸入 range1 的值:  8  
  • 輸入 range2 的值:  1980  
  • 原值    1: select * from emp_random where empno between &range1 and &range2  
  • 新值    1: select * from emp_random where empno between 8 and 1980  
  •   
  • 已選擇1973行。  
  •   
  •   
  • 執行計劃  
  • ----------------------------------------------------------  
  • Plan hash value: 731629521  
  •   
  • --------------------------------------------------------------------------------  
  • | Id  | Operation     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |  
  • --------------------------------------------------------------------------------  
  • |   0 | SELECT STATEMENT  |        |  1972 | 72964 |  1735   (1)| 00:00:21 |  
  • |*  1 |  TABLE ACCESS FULL| EMP_RANDOM |  1972 | 72964 |  1735   (1)| 00:00:21 |  
  • --------------------------------------------------------------------------------  
  •   
  • Predicate Information (identified by operation id):  
  • ---------------------------------------------------  
  •   
  •    1 - filter("EMPNO"<=1980 AND "EMPNO">=8)  
  •   
  •   
  • 統計信息  
  • ----------------------------------------------------------  
  •       1  recursive calls  
  •       0  db block gets  
  •        6388  consistent gets  
  •       0  physical reads  
  •       0  redo size  
  •      103922  bytes sent via SQL*Net to client  
  •        1961  bytes received via SQL*Net from client  
  •     133  SQL*Net roundtrips to/from client  
  •       0  sorts (memory)  
  •       0  sorts (disk)  
  •        1973  rows processed  



概括以下,

BITMAP EMPNO (Range) B-TREE
Consistent Reads Physical Reads Consistent Reads Physical Reads
2463 0 1-2300 6410 0
2114 0 8-1980 6388 0
2572 0 1850-4250 6418 0
3172 0 28888-31850 6456 0
2762 0 82900-85478 6431 0
7254 0 984888-1000000 7254 0

從這裏能夠看出,位圖索引要優於btree索引,這是由於btree索引的cluster  factor 較大,從而優化器選擇了全表掃描。即使在emp_normal 表下,即clustering factor較小時,位圖索引btree索引至關的。所以在distinct cardinality 較大的狀況下,範圍掃描的效率位圖索引也是不遜色與btree索引。
總結以下:
位圖索引的查詢性能常常是優於btree索引的,即使在distinct cardinality較大的狀況下
位圖索引不適合與dml頻繁的環境
位圖索引適用於DSS系統
位圖索引能夠進行邏輯運算,多個索引和同時在查詢語句中發揮做用,這是一個很是重要的地方

相關文章
相關標籤/搜索