位圖索引


     位圖索引主要針對大量相同值的列而創建的索引。(例如:性別), 位圖索引相對於傳統的B*樹索引,在葉子節點上采用了完全不同的結構組織方式。傳統B*樹索引將每一行記錄保存為一個葉子節點,上面記錄對應的索引列取值和行rowid信息。而位圖索引將每個可能的索引取值組織為一個葉子節點。每個位圖索引的葉子節點上,記錄着索引鍵值、該索引鍵值的起始截止rowid和一個位圖向量串。從本質上將,位圖索引通過一個bit位來記錄一個數據行是否存在對應鍵值。這種方式存儲數據,相對於B*Tree索引,占用的空間非常小,創建和使用非常快. 這樣做對比傳統的B*樹索引空間節省高。而且可以借助計算機位圖運算的快速特性來提高索引結果利用率。

一、位圖索引的創建

創建語法很簡單,就是在普通索引創建的語法中index前加關鍵字bitmap即可,例如:

create bitmap index emp_job_bitmap_idx on emp(job);

二、位圖索引的原理

clip_image001

1、 索引塊的一個索引行中存儲鍵值、起止Rowid,以及這些鍵值的位置編碼,

2、 位置編碼中的每一位表示鍵值對應的數據行的有無.位數=表的總記錄數

3、 所需的位圖個數=索引列的不同鍵值多少,列的不同值越少,所需的位圖就越少

4、 當根據鍵值查詢時,可以根據起始Rowid和位圖狀態,快速定位數據.

5、 這樣與B*樹那樣直接保存rowid的區別就在於每次都要進行rowid的換算工作。

三、例子

以EMP表為例

 1 CREATE TABLE EMP (
 2     EMPNO NUMBER (4) PRIMARY KEY,
 3     ENAME VARCHAR2 (10),
 4     JOB VARCHAR2 (9),
 5     MGR NUMBER (4),
 6     HIREDATE DATE,
 7     SAL NUMBER (7, 2),
 8     COMM NUMBER (7, 2),
 9     DEPNO NUMBER (4)
10 );

插入數據

INSERT INTO EMP VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,null,20);
INSERT INTO EMP VALUES (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO EMP VALUES (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO EMP VALUES (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
INSERT INTO EMP VALUES (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
INSERT INTO EMP VALUES (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
INSERT INTO EMP VALUES (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
INSERT INTO EMP VALUES (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
INSERT INTO EMP VALUES (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
INSERT INTO EMP VALUES (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);
INSERT INTO EMP VALUES (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO EMP VALUES (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);

select distinct "JOB" from emp

clip_image003

創建位圖索引

create bitmap index emp_job_bitmap_idx on emp(job);

查詢

SELECT EMPNO,ENAME,SAL FROM EMP WHERE JOB = 'SALESMAN';

上述查詢語句的目的是在EMP表中查詢工作崗位是SALESMAN的員工的員工號,姓名和薪水,此時假設已經在EMP表的JOB列建立了位圖索引,其結構如下圖所示。

clip_image005

在該索引圖中,共用5 類JOB,每類JOB 對應14 個比特位(對應14 行記錄),其中某行的在該列的值與JOB 值對應則使用比特1 表示,如JOB = ‘CLERK’,第一行在該列對應的值是CLERK,就用比特1表示。否則用比特0表示,其他JOB類類似。

clip_image007

SELECT EMPNO,ENAME,SAL FROM EMP WHERE JOB = 'SALESMAN'

通過位圖索引掃描JOB=‘CLERK’對應的位圖記錄,找到值為1 的行記錄,即找到需要查找數據。

clip_image009

(驗證了每次都要進行rowid的換算工作)

四、位圖索引與數據DML鎖定

4.1 Bitmap測試

用實驗說明為什么位圖索引不適合OLTP,比較適合OLAP。即:DML操作比較多的表不適合使用位圖索引。

以上面的EMP表為例,我們已經在該表的JOB字段建立了位圖索引

Session1:

select distinct sid from v$mystat;

UPDATE EMP SET JOB='CLERK' WHERE ENAME='ALLEN';

clip_image011

Session2

select distinct sid from v$mystat;

UPDATE EMP SET JOB='SALESMAN' WHERE ENAME='SMITH';

clip_image013

select * from v$lock where sid in(10,128) order by type;
select sid,status,last_call_et,blocking_session from v$session where sid in(10,128);

可以看見10阻塞了128 。盡管他們修改的不是同一列。

clip_image015

Session1提交

clip_image017

Session2 阻塞解除,自動執行了

clip_image019

4.2 B樹索引測試。

如果使用B樹索引,就不存在阻塞情況了。創建同樣的EMP表,使用EMPNO字段,英愛該字段為primary key,為B樹索引。

Session1

SQL> select distinct sid from v$mystat;

SID

----------

10

SQL> UPDATE EMP SET EMPNO=8000 WHERE ENAME='ALLEN';

1 row updated.

SQL>

clip_image021

Session2

SQL> select distinct sid from v$mystat;

SID

----------

421

SQL> UPDATE EMP SET EMPNO=9000 WHERE ENAME='SMITH';

1 row updated.

SQL>

clip_image023

select sid,status,last_call_et,blocking_session from v$session where sid in(10,421);

兩個窗口均為INACTIVE

clip_image025

五、位圖索引的特點

5.1 Bitmap索引的存儲空間更小

相對於B*Tree索引,位圖索引由於只存儲鍵值的起止Rowid和位圖,占用的空間非常少. bitmap的空間占用主要與以下因素相關:

       a.表的總記錄數

       b.索引列的鍵值多少,列的不同值越少,所需的位圖就越少.

5.2 Bitmap索引創建的速度更快

位圖索引創建時不需要排序, B*Tree索引則在創建時需要排序,定位等操作,速度要慢得多.

5.3 Bitmap索引允許鍵值為空

Bitmap索引允許鍵值為空 B*Tree索引由於不記錄空值,當基於is null的查詢時,會使用全表掃描, 而對位圖索引列進行is null查詢時,則可以使用索引.

5.4 Bitmap索引對表記錄的高效訪問

當使用count(XX),可以直接訪問索引就快速得出統計數據.

當根據位圖索引的列進行and,or或 in(x,y,..)查詢時,直接用索引的位圖進行或運算,在訪問數據之前可事先過濾數據.

5.5 Bitmap索引對批量DML操作只需進行一次索引

由於通過位圖反映數據情況,批量操作時對索引的更新速度比B*Tree索引一行一行的處理快得多.

5.6 Bitmap索引的鎖機制

對於B*Tree索引,insert操作不會鎖定其它會話的DML操作. 而位圖索引,由於用位圖反映數據,不同會話更新相同鍵值的同一位圖段,insert、update、delete相互操作都會發鎖定。

原文

位圖索引(Bitmap Index)——索引共用

B樹索引和位圖索引的區別!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM