您好,登錄后才能下訂單哦!
位圖索引區(qū)別于傳統(tǒng)B*樹索引有兩個(gè)結(jié)構(gòu)特點(diǎn):其一是葉子節(jié)點(diǎn)上是一個(gè)可能的索引列取值對(duì)應(yīng)一個(gè)葉子節(jié)點(diǎn)。另一個(gè)就是葉子節(jié)點(diǎn)上通過一個(gè)位圖向量表示對(duì)應(yīng)行是否取定這個(gè)索引值。
使用位圖向量記錄對(duì)應(yīng)行的取值情況不僅可以帶來(lái)存儲(chǔ)空間上的節(jié)省,而且可以借助計(jì)算機(jī)位圖運(yùn)算的快速特性來(lái)提高索引結(jié)果利用率。下面我們通過模擬情況來(lái)進(jìn)行分析。
Bitmap Index模擬說(shuō)明
假設(shè)存在數(shù)據(jù)表T,有兩個(gè)數(shù)據(jù)列A和B,取值如下。
序號(hào) |
A |
B |
1 |
L |
1 |
2 |
T |
2 |
3 |
L |
2 |
4 |
M |
1 |
對(duì)兩個(gè)數(shù)據(jù)列A、B分別建立位圖索引:idx_t_bita和idx_t_bitb。兩個(gè)索引對(duì)應(yīng)的存儲(chǔ)邏輯結(jié)構(gòu)如下:
Idx_t_bita索引結(jié)構(gòu),對(duì)應(yīng)的是葉子節(jié)點(diǎn):
索引鍵值 |
起始rowid |
結(jié)束rowid |
位圖向量 |
L |
xxx |
ttt |
1010 |
T |
xxx |
ttt |
0100 |
M |
xxx |
ttt |
0001 |
Idx_t_bitb索引結(jié)構(gòu),對(duì)應(yīng)的是葉子節(jié)點(diǎn):
索引鍵值 |
起始rowid |
結(jié)束rowid |
位圖向量 |
1 |
xxx |
ttt |
1001 |
2 |
xxx |
ttt |
0110 |
|
|
|
|
對(duì)查詢“select * from t where b=1 and (a=’L’ or a=’M’)”
分析:位圖索引使用方面,和B*索引有很大的不同。B*索引的使用,通常是從根節(jié)點(diǎn)開始,經(jīng)過不斷的分支節(jié)點(diǎn)比較到最近的符合條件葉子節(jié)點(diǎn)。通過葉子節(jié)點(diǎn)上的不斷Scan操作,“掃描”出結(jié)果集合rowid。
而位圖索引的工作方式截然不同。通過不同位圖取值直接的位運(yùn)算(與或),來(lái)獲取到結(jié)果集合向量(計(jì)算出的結(jié)果)。
針對(duì)實(shí)例SQL,可以拆分成如下的操作:
1、a=’L’ or a=’M’
a=L:向量:1010
a=M:向量:0001
or操作的結(jié)果,就是兩個(gè)向量的或操作:結(jié)果為1011。
2、結(jié)合b=1的向量
中間結(jié)果向量:1011
B=1:向量:1001
and操作的結(jié)果,1001。翻譯過來(lái)就是第一和第四行是查詢結(jié)果。
3、獲取到結(jié)果rowid
目前知道了起始rowid和終止rowid,以及第一行和第四行為操作結(jié)果??梢酝ㄟ^試算的方法獲取到結(jié)果集合rowid。
上面的操作演算過程,說(shuō)明了兩個(gè)問題:
位圖索引是可以多索引共同合作操作的,不像B*樹索引只有一個(gè)會(huì)加入結(jié)果集合;
位圖索引的工作是通過位邏輯運(yùn)算,非掃描操作;
實(shí)際試驗(yàn)
下面我們通過一系列的實(shí)驗(yàn),來(lái)進(jìn)一步觀察結(jié)果。
實(shí)驗(yàn)環(huán)境構(gòu)建
SQL> create table t as select owner owner1, object_type type1, owner owner2, object_type type2 from dba_objects;
Table created
SQL> desc t;
Name Type Nullable Default Comments
------ ------------ -------- ------- --------
OWNER1 VARCHAR2(30) Y
TYPE1 VARCHAR2(19) Y
OWNER2 VARCHAR2(30) Y
TYPE2 VARCHAR2(19) Y
SQL> create index idx_t_owner1 on t(owner1);
Index created
SQL> create index idx_t_type1 on t(type1);
Index created
SQL> create bitmap index idx_t_owner2bit on t(owner2);
Index created
SQL> create bitmap index idx_t_type2bit on t(type2);
Index created
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);
PL/SQL procedure successfully completed
常規(guī)索引實(shí)驗(yàn)
我們構(gòu)建的環(huán)境中,字段和類型完全相同。區(qū)別就在于使用的索引類型差異。下面我們先進(jìn)行常規(guī)索引實(shí)驗(yàn)。
//為防止影響執(zhí)行計(jì)劃,先禁用Bitmap Index
SQL> alter index idx_t_owner2bit unusable;
Index altered
SQL> alter index idx_t_type2bit unusable;
Index altered
SQL> set pagesize 1000;
SQL> set linesize 1000;
SQL> explain plan for select * from t where owner1='SCOTT' and type1='TABLE';
已解釋。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 2154532428
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time|
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 28 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_T_OWNER1 | 28 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("TYPE1"='TABLE')
2 - access("OWNER1"='SCOTT')
已選擇15行。
注意:owner1和type1上均有B*索引,而且均出現(xiàn)在where條件上。結(jié)果采用的Scan方式,而且只使用到了一個(gè)索引對(duì)象。
Bitmap Index索引實(shí)驗(yàn)
此次使用Bitmap Index列對(duì)應(yīng)查詢條件。
//索引處理
SQL> alter index idx_t_type2bit rebuild;
Index altered
SQL> alter index idx_t_owner2bit rebuild;
Index altered
SQL> alter index idx_t_owner1 unusable;
Index altered
SQL> alter index idx_t_type1 unusable;
Index altered
SQL> explain plan for select * from t where owner2='SCOTT' and type2='TABLE';
已解釋。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------
Plan hash value: 244872826
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 61 | 1708 | 13 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | T | 61 | 1708 | 13 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
| 3 | BITMAP AND | | | | | |
|* 4 | BITMAP INDEX SINGLE VALUE| IDX_T_TYPE2BIT | | | | |
|* 5 | BITMAP INDEX SINGLE VALUE| IDX_T_OWNER2BIT | | | | |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("TYPE2"='TABLE')
5 - access("OWNER2"='SCOTT')
已選擇18行。
在一個(gè)SQL中,兩個(gè)Bitmap索引均使用到。
下面實(shí)驗(yàn)一個(gè)比較復(fù)雜的條件。
SQL> explain plan for select * from t where owner2='SCOTT' and (type2='TABLE' or type2='INDEX');
已解釋。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------
Plan hash value: 3499411373
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 122 | 3416 | 24 (5)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | T | 122 | 3416 | 24 (5)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP AND | | | | | |
|* 4 | BITMAP INDEX SINGLE VALUE | IDX_T_OWNER2BIT | | | | |
| 5 | BITMAP OR | | | | | |
|* 6 | BITMAP INDEX SINGLE VALUE| IDX_T_TYPE2BIT | | | | |
|* 7 | BITMAP INDEX SINGLE VALUE| IDX_T_TYPE2BIT | | | | |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("OWNER2"='SCOTT')
6 - access("TYPE2"='INDEX')
7 - access("TYPE2"='TABLE')
已選擇21行。
請(qǐng)注意Bitmap系列and和or操作,和我們?cè)陂_篇中做的模擬計(jì)算如出一轍。
Bitmap Index是一種適應(yīng)范圍比較窄,但是特效針對(duì)性很強(qiáng)的索引類型。在一些場(chǎng)合下合適使用,可以帶來(lái)出乎意料的效果。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。