點陣圖索引(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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle點陣圖索引對DML操作的影響Oracle索引
- 點陣圖索引(轉載)索引
- Python點陣圖索引學習Python索引
- 點陣圖索引的工作原理 - Richard索引
- Android Bitmap(點陣圖)詳解Android
- 點陣圖(bitmap)原理以及實現
- Redis 基礎 -- 點陣圖(bitmap)資料結構和 bitmap的常用命令Redis資料結構
- 點陣圖
- MySQL點陣圖索引解決使用者畫像問題MySql索引
- 點陣圖與ERP場景
- ClickHouse 留存、路徑、漏斗、session 點陣圖 roaringbitmap 點陣圖最佳化Session
- MySQL點陣圖索引解決使用者畫像問題(簡化建立流程)MySql索引
- PHP 文字生成點陣圖PHP
- Redis 應用-點陣圖Redis
- 點陣圖字型匯入
- 可寫點陣圖(WriteableBitmap)
- 慢查詢、pipline、釋出訂閱、 bitmap點陣圖、 hyperloglog、geo、持久化持久化
- PHP掃描圖片轉點陣 二維碼轉點陣PHP
- 演算法-點陣圖排序演算法排序
- Elasticsearch之索引模板index template與索引別名index aliasElasticsearch索引Index
- 代理模式+react+ 圖片佔點陣圖模式React
- layui圖片懶載入-loading佔點陣圖UI
- 如何利用散點圖矩陣進行資料視覺化矩陣視覺化
- hash join構建點陣圖的理解
- VC 點陣圖按鈕CBitmapButton的使用
- 雜湊表擴充套件—點陣圖套件
- DM7 陣列索引陣列索引
- MySQL的index merge(索引合併)導致資料庫死鎖分析與解決方案MySqlIndex索引資料庫
- Oracle assm三級點陣圖結構解析OracleSSM
- Android實現二值點陣圖識別Android
- MySql 三大知識點——索引、鎖、事務!MySql索引
- oracle全文索引之commit與DML操作Oracle索引MIT
- 尋找陣列的中心索引陣列索引
- DM8管理陣列索引陣列索引
- iOS自定義控制元件:自定義TableView、CollectionView空資料佔點陣圖iOS控制元件View
- 【思維導圖-索引篇】搞定資料庫索引就是這麼簡單索引資料庫
- 索引的知識要點與操作索引
- UITableView佔點陣圖的低耦合性設計UIView
- 如何優雅地使用Redis之點陣圖操作Redis