點陣圖索引(Bitmap Index)——點陣圖索引與資料DML鎖定
點陣圖索引相對於傳統的B*樹索引,在葉子節點上採用了完全不同的結構組織方式。傳統B*樹索引將每一行記錄儲存為一個葉子節點,上面記錄對應的索引列取值和行rowid資訊。而點陣圖索引將每個可能的索引取值組織為一個葉子節點。每個點陣圖索引的葉子節點上,記錄著該索引鍵值的起始截止rowid和一個點陣圖向量串。
從本質上將,點陣圖索引透過一個bit位來記錄一個資料行是否存在對應鍵值。這樣做對比傳統的B*樹索引空間節省高。這樣與B*樹那樣直接儲存rowid的區別就在於每次都要進行rowid的換算工作。
行級鎖是Oracle從問世以來一直引以為豪的重要特性。行級鎖的含義就是在進行insert、update和delete等DML操作時,進行鎖定的範圍都是最小的資料行一級。這樣能夠保證資料庫具有最大程度支援併發的能力。
在使用傳統的B*樹索引和Bitmap索引之後,這種特性有無變化。是否Bitmap Index具有B*樹索引不可比擬的優勢呢?下面我們透過增加、修改和刪除三個方面的實驗來進行說明。
環境準備
SQL> select * from v$version where rownum<2;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Prod
SQL> create table t (col varchar2(10));
Table created
SQL> create bitmap index idx_t_colbit on t(col);
Index created
插入實驗
當向資料表進行資料插入的時候,可以觀察到使用點陣圖索引時的鎖定現象。下面分別從單會話和多會話兩個方面實驗。
單session實驗
//會話一
SQL> select sid from v$mystat where rownum<2;
SID
----------
150
SQL> insert into t values ('T');
1 row inserted
SQL> commit;
Commit complete
在事務未提交時,鎖狀態資訊為:
SQL> select addr, sid, type, id1,id2, lmode,request,block from v$lock where sid=150;
ADDR SID TYPE ID1 ID2 LMODE REQUEST BLOCK
-------- ---------- ---- ---------- ---------- ---------- ---------- ----------
333415A4 150 TM 55439 0 3 0 0
33383BE4 150 TX 262177 867 6 0 0
此時和一般的行鎖沒有特殊之處。針對資料表有一個共享鎖,對事務存在一個獨佔鎖。
多session實驗
當我們進行多個會話同時插入資料時。
//session1:sid=150
SQL> select * from t;
COL
----------
L
M
T
T
SQL> insert into t values ('M');
1 row inserted
此時,session2進行插入操作。
//另起一個會話session2
SQL> select sid from v$mystat where rownum<2;
SID
----------
148
//插入當前沒有的資料值,不會阻塞;
SQL> insert into t values ('X');
1 row inserted
//插入當前存在,但是改值沒有事務涉及到的數值,不會阻塞;
SQL> insert into t values ('L');
1 row inserted
//插入當前正在被修改的值,被阻塞!
SQL> insert into t values ('M');
(會話阻塞!)
此時,我們檢查鎖狀態資訊。
SQL> select addr, sid, type, id1,id2, lmode,request,block from v$lock where sid=150 or sid=148;
ADDR SID TYPE ID1 ID2 LMODE REQUEST BLOCK
-------- ---------- ---- ---------- ---------- ---------- ---------- ----------
33834398 148 TX 327699 1074 0 4 0
333415A4 150 TM 55439 0 3 0 0
33341668 148 TM 55439 0 3 0 0
3337E84C 148 TX 524319 1051 6 0 0
33383BE4 150 TX 327699 1074 6 0 1
從上面我們可以看出,此時發生了阻塞。Session2(sid=148)請求session1(sid=150)獨佔的事務資源,要求共享(lmode=4)。所以session2被阻塞。
在傳統的Oracle概念中,insert通常是不會被阻塞的,除非存在主鍵資訊事務內重複的情況。資料表T沒有主鍵,只有可能是由於Bitmap Index的原因造成的鎖定,鎖定範圍是由於session1插入的相同值。
結論:在進行insert插入的時候,如果資料列存在點陣圖索引,Oracle會將資料表中當前具有該值的所有行進行鎖定。這裡行鎖機制範圍擴大化,一個插入和事務,會影響到多行資料。
修改操作
修改中,我們涉及到將一個索引值修改為另一個索引值的情況。
單session實驗
//session1修改操作
SQL> update t set col='M' where col='L';
1 row updated
SQL> update t set col='S' where col='M';
2 rows updated
SQL> rollback;
Rollback complete
在單session情況下,進行修改是不會引起阻塞的,因為會話對資源的佔有特性。
多session實驗
當存在多個會話的時候,就存在出現block的可能。
//新增資料列
SQL> select * from t;
COL ID
---------- ----------
M 1
L 2
T 3
T 4
L 5
//session1(sid=150)
SQL> update t set col='L' where id=3;
1 row updated
//session2(sid=148)
SQL> update t set col='X' where id=4;
(被阻塞!)
SQL> update t set col='X' where id=2;
(被阻塞!)
出現了大量的block現象,而且範圍很大。Session1(sid=150)只是修改了id=3的資料行,卻影響到了原有取值(col=’T’)和新取值(col=’L’)的所有資料行被鎖定。
結論:在進行update的時候,Bitmap Index帶來的鎖定範圍是很大的。從原有值到新設定的值都會被鎖定。
刪除操作
單會話實驗
SQL> select * from t;
COL ID
---------- ----------
M 1
L 2
T 3
T 4
L 5
SQL> delete t where id=3;
1 row deleted
SQL> delete t where id=4;
1 row deleted
SQL> delete t where id=5;
1 row deleted
SQL> rollback;
Rollback complete
單會話情況下,是不會發生阻塞現象的。
多會話實驗
當進行刪除的時候,是否會發生同值資料行鎖定的情況呢?
//session1(sid=150)
SQL> select * from t;
COL ID
---------- ----------
M 1
L 2
T 3
T 4
L 5
SQL> delete t where id=4;
1 row deleted
此時,另一個會話嘗試刪除相同col的不同資料行。
//session2(sid=148)
SQL> delete t where id=5;(不同col值的情況,不會阻塞)
1 row deleted
SQL> delete t where id=3;(雖然是不同行,但是由於col相同,會被阻塞!)
(會話被阻塞!)
結論:在刪除的時候,Oracle會鎖定所有刪除行對應鍵值的所有行。
綜合上述的論定,我們可以看到Bitmap Index的一個重要缺陷,就是鎖定範圍的擴大化。當我們對一個有點陣圖索引的資料表進行DML操作的時候,Oracle會由於Bitmap Index鎖定過多的資料行,極端的情況可能會由於一行資料的修改而鎖定大部分的資料記錄。這種情況在單會話的情況下是允許的,但是一旦是在多會話併發的環境下,進行這樣的DML操作就是一場災難!
資料庫的一個重要指標就是並行特性,並行特性的好壞決定著系統整體效能。一旦發生這樣的阻塞,隨之而來就是並行度減少和等待時間增加。這個是大部分OLTP系統不希望看到的。
所以,我們也就發現了Bitmap Index適應性的一個重要侷限,就是對併發操作支援度差,不適應與OLTP系統。Bitmap Index的容量優勢和速率優勢,都不足以彌補這方面的劣勢。對OLTP系統,我們不要輕易使用Bitmap Index。
而對於資料倉儲系統DW和OLAP系統,Bitmap Index能發揮出更大的優勢。首先是這樣的環境下,資料量達到海量級別,對資料檢索效能要求高。這樣,體積精簡、效能優良的Bitmap Index優勢明顯。更重要的是,這樣的系統資料變化DML較少,即使發生也都是大面積的單執行緒會話匯入操作,可以迴避Bitmap Index併發缺陷。
對一個物件,要理解優勢、劣勢和適應環境,才能做到熟練掌握、果斷應用。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-694955/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 點陣圖索引(Bitmap Index)——索引共用索引Index
- 點陣圖索引(Bitmap Index)——從B*樹索引到點陣圖索引索引Index
- oracle 點陣圖索引(bitmap index)Oracle索引Index
- 點陣圖索引:原理(BitMap index)索引Index
- 點陣圖索引(bitmap-index)索引Index
- bitmap index點陣圖索引系列(一)Index索引
- 【Bitmap Index】B-Tree索引與Bitmap點陣圖索引的鎖代價比較研究Index索引
- zt_深入理解bitmap index點陣圖索引Index索引
- 【索引】Bitmap點陣圖索引與普通的B-Tree索引鎖的比較索引
- B-Tree索引與Bitmap點陣圖索引的鎖代價比較研究索引
- Oracle索引——點陣圖索引Oracle索引
- 【點陣圖索引】在點陣圖索引列上進行更新操作的鎖代價研究索引
- 點陣圖索引.sql索引SQL
- oracle點陣圖索引對DML操作的影響Oracle索引
- Oracle-點陣圖索引Oracle索引
- 【基礎知識】索引--點陣圖索引索引
- Python點陣圖索引學習Python索引
- 點陣圖索引的工作原理 - Richard索引
- oracle10g r2_sql tuning_bitmap index點陣圖索引_index效能小測試OracleSQLIndex索引
- Linux 核心資料結構:點陣圖(Bitmap)Linux資料結構
- 關於點陣圖索引的split及bitmap to rowid實現問題索引
- B樹索引和點陣圖索引的結構介紹索引
- Android Bitmap(點陣圖)詳解Android
- 點陣圖(bitmap)原理以及實現
- 關於ORACLE點陣圖索引內部淺論Oracle索引
- 使用點陣圖連線索引優化OLAP查詢索引優化
- oracle dml與索引index(一)Oracle索引Index
- PHP實現bitmap點陣圖排序求交集PHP排序
- 使用點陣圖連線索引最佳化OLAP查詢索引
- 點陣圖
- MySQL點陣圖索引解決使用者畫像問題MySql索引
- 使用點陣圖索引和星形轉換優化OLAP查詢索引優化
- 使用點陣圖選單項——設定點陣圖型別標記 (轉)型別
- 使用點陣圖選單項——建立點陣圖 (轉)
- 教你如何成為Oracle 10g OCP - 第九章 物件管理(9) - 點陣圖(Bitmap)索引Oracle 10g物件索引
- 教你如何成為Oracle 10g OCP - 第九章 物件管理(10) - 點陣圖(Bitmap)索引Oracle 10g物件索引
- 點陣圖排序排序
- 關於B*tree索引(index)的中度理解及bitmap 索引的一點探究(zt)索引Index