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系統
位圖索引能夠進行邏輯運算,多個索引和同時在查詢語句中發揮做用,這是一個很是重要的地方