正常的b樹索引對包含每行記錄的rowid與索引鍵值。位圖索引不會直接存儲rowid,每個不同的鍵值都有一個位圖,這就是為什麼建立位圖索引的列要有較少的distinct值的原因。位圖中的每一位映射到一個可能的rowid,位圖中每一位的特定值代表是否存在有價值的記錄,是以位圖中存儲了關于特定行和相關的rowid。如果rowid的值與條件比對在rowid的位置存儲“1”,不比對存儲“0”。oracle會壓
縮位圖的存儲。
建立位圖索引
create bitmap index index_name on table_name(columns);oracle将建立一系列的位圖,列中每個特定值都會被使用。例如,如果建立位圖索引的列有'east'和'central'兩個值,那麼将會為'east'和'central'建立位圖。如果是複合位圖索引,那麼位圖将是由
任何一組可能的排列值組成。
位圖索引的使用
1.列有較低的基數:較少的distinct值
2.位圖索引對于包含較長where子句或聚合查詢(包含sum,count或其它聚合函數)的ad hoc查詢很有幫助
3.表行記錄很多(比如有1,000,000行記錄有10,000個distinct值)
4.對于表執行ad hoc查詢很頻繁
5.資料倉庫環境(dss系統)。位圖索引對于聯機事務處理(oltp)不适用這是由于位圖索引的鎖機制造成的,隻鎖定單個位圖的位置是不能實作的。能夠被鎖定的最小位圖量是一個位圖段,它的大小可以達到資料塊的一半。改變一行記錄會造成一個位圖段被鎖定,而實際上隻改變了一行記錄。當有許多update,insert或delete語句被執行時,影響會更明顯。在資料倉庫中當資料批量加載或更新時這種影響不是問題。
6.位圖連接配接索引是9中引入的,通過連接配接可以避免在連接配接條件上預先建立位圖索引的必要
位圖索引的限制
1.不能用于rbo
2.不能用于分區表的全局索引
3.不支援聯機建立或重建
4.對位圖索引使用直接路徑加載,"sorted_index"标記不能應用
5.位圖索引不能用于引用完整性
6.位圖索引不能定義為unique
7.在9i之前,當建立一個索引組織表時不能使用位圖索引,從9i開始才支援。
8.對域索引不能使用bitmap
與b樹索引相比的優點
1.減少了許多ad hoc查詢的響應時間
2.大幅減少了存儲空間
a)有少量distinct值的單列位圖索引
如果位圖索引是建立在一個唯一鍵上,它将比正常b樹索引使用的空間更多。然後,如果列中有成百上千個重複值時,位圖索引通常要比正常b樹索引所使用的空間減少25%。位圖是以壓縮的格式來進行存儲的。
b)在多列上建立位圖索引
位圖索引與b樹索引相比可以大量節省存儲空間。在資料庫中隻包含b樹索引,必須對查詢中所使用的列進行預測并對這些列建立一個複合b樹索引。多列複合b樹索引不僅需要大量的空間,還要進行排序。對于在(marital_status,region,gender)上建立的b樹索引,對于隻通路region與dender在前導列marital_status有太多distinct值的情況下是沒有用的。為了使用索引,必須對這些列的其它組合方
式建立索引。簡單來說,對于三個低基數列就有6種組合的b樹索引。必須對建立那種組合的b樹索引和需要的存儲空間進行考慮。b樹索引可以解決這種問題。位圖索引可以在查詢執行時進行有效的組合,是以三個小的單列位圖索引可以完成6個三列b樹索引所做的事情。
3.非常影響并行dml與加載
位圖索引适合資料倉庫程式但不适合有高并發insert,update與delete系統。在資料倉庫環境中,資料通常是批量插入和更新的。索引維護操作直到每個dml操作結束才執行。
4.包含null值的記錄
位圖索引的使用技巧
1.對所有可能的列定義not null限制将會減少存儲空間,因為這将不會為null值建立位圖。
2.使用固定長度的資料類型将會減少存儲空間
3.增加create_bitmap_area_size參數可以提高查詢處理速度。這個參數決定了對位圖建立所配置設定的記憶體大小。這個參數決定了用于合并位圖從範圍掃描索引執行檢索所使用的記憶體。
位圖索引的例子
marital_ status region gender income_level
--------------- -------- ------- ------------
101 single east male bracket_1
102 married central female bracket_4
103 married west female bracket_2
104 divorced west male bracket_4
105 single central female bracket_2
106 married central female bracket_3
國灰marital_status,region,gender與income_level都是低基數列(對于matil_status與region隻有三個可能的值,對于gender有兩個可能的值,income_level列有四個可能的值)。在這些列上适合建立位圖索引。在customer#上不适合建立位圖索引,因為這個列有高基數。相反,一個唯一的b樹索引将會提供最好的檢索效率。
在這個例子中,region列的位圖索引,它包括三個單獨的位圖
region='east' region='central' region='west' ## customer #
1 0 0 < == 101
0 1 0 <== 102
0 0 1 <== 103
0 0 1 <== 104
0 1 0 <== 105
0 1 0 <== 106 位圖中的每個條目或位關聯到customer表中的單獨一行記錄。每一位的值依賴于表中相關行的值。例如,位region='east'包含一個1作為它的第一位。這是因為region='east'在表customer中的第一行存在。region='east'在其它行位為0,是因為其它行的region列不包含'east'。 下面的查詢是要查詢在中部或西部地區有多少已婚的客戶: select count(*) from customer where marital_status = 'married' and region in ('central','west'); 位圖索引可以非常有效的通過僅僅計算結果位圖中為1的數量來進行處理。 status = 'married' region = 'central' region = 'west' 0 0 0 1 1 0 1 0 1 0 and ( 0 or 1 ) 0 1 0 1 1 0 0 0 0 1 1 1 ==> 2nd row
= 1 1 1 ==> 3rd row
0 and 1 = 0
0 1 0
1 1 1 ==> last row