本文為您介紹Hologres中位元影像索引Bitmap的使用相關內容。
Bitmap介紹
在Hologres中,bitmap_columns
屬性指定位元影像索引,是資料存放區之外的獨立索引結構,以位元影像向量結構加速等值比較情境,能夠對檔案塊內的資料進行快速的等值過濾,適用於等值過濾查詢的情境。使用文法如下。
-- Hologres V2.1版本起支援的文法
CREATE TABLE <table_name> (...) WITH (bitmap_columns = '[<columnName>{:[on|off]}[,...]]');
-- 所有版本支援的文法
CREATE TABLE <table_name> (...);
CALL set_table_property('<table_name>', 'bitmap_columns', '[<columnName>{:[on|off]}[,...]]');
參數 | 說明 |
table_name | 表名稱。 |
columnName | 列名稱。 |
on | 當前欄位開啟位元影像索引。 |
off | 當前欄位關閉位元影像索引。 |
使用建議
適合將等值查詢的列設定為Bitmap,能夠快速定位到合格資料所在的行號。但需要注意的是Bitmap對於基數比較高(重複資料較少)的列會有比較大的額外儲存開銷。
不建議為每一列都設定Bitmap,不僅會有額外儲存開銷,也會影響寫入效能(因為要為每一列構造Bitmap)。
不建議為實際內容為JSON,但儲存為text類型的列設定Bitmap。
使用限制
只有列存表和行列共存表支援設定Bitmap,行存表不支援設定。
Bitmap指定的列可以為空白。
目前的版本預設所有TEXT類型的列都會被隱式地設定為Bitmap。
設定位元影像索引命令可以在事務之外單獨使用,表示修改位元影像索引列,修改之後非立即生效,位元編碼構建和刪除在後台非同步執行,詳情請參見ALTER TABLE。
bitmap_columns
屬性僅支援設為on
或off
,Hologres V2.0版本起,不支援將bitmap_columns
屬性設為auto
。
技術原理
Bitmap不同於Distribution Key和Clustering Key,Bitmap是資料存放區之外的獨立索引,設定了Bitmap索引之後,系統會將列對應的數值產生一個二進位字串,用於表示取值所在位置的Bitmap,當查詢命中Bitmap時,會快速定位到資料所在的行號(Row Number),從而快速過濾出資料。但Bitmap並不是沒有開銷的,對於以下情境需要注意事項如下:
列的基數較高(重複資料較少)情境:假如列的基數較高,那麼就會為每一個值產生一個Bitmap,當非重複值很多的時候,就會形成稀疏數組,佔用儲存較多。
大寬表的每一列都設定為Bitmap情境:如果為大寬表的每一列都設定為Bitmap,那麼在寫入時每個值都需要構建成Bitmap,會有一定的系統開銷,從而影響寫入效能。
綜上,Bitmap本質上是空間換時間的手段,對於資料分布比較均勻的列有比較高的性價比。
如下樣本,可以通過explain SQL
查看是否命中Bitmap索引。在執行計畫中,有Bitmap Filter
則說明命中Bitmap索引。
V2.1版本起支援的文法:
CREATE TABLE bitmap_test ( uid int NOT NULL, name text NOT NULL, gender text NOT NULL, class text NOT NULL, PRIMARY KEY (uid) ) WITH ( bitmap_columns = 'gender,class' ); INSERT INTO bitmap_test VALUES (1,'張三','男','一班'), (2,'李四','男','三班'), (3,'王五','女','二班'), (4,'趙六','女','二班'), (5,'孫七','男','二班'), (6,'周八','男','三班'), (7,'吳九','女','一班'); explain SELECT * FROM bitmap_test where gender='男' AND class='一班';
所有版本支援的文法:
begin; create table bitmap_test ( uid int not null, name text not null, gender text not null, class text not null, PRIMARY KEY (uid) ); call set_table_property('bitmap_test', 'bitmap_columns', 'gender,class'); commit; INSERT INTO bitmap_test VALUES (1,'張三','男','一班'), (2,'李四','男','三班'), (3,'王五','女','二班'), (4,'趙六','女','二班'), (5,'孫七','男','二班'), (6,'周八','男','三班'), (7,'吳九','女','一班'); explain SELECT * FROM bitmap_test where gender='男' AND class='一班';
如下所示執行計畫結果中有Bitmap Filter
運算元,說明命中Bitmap索引。
Bitmap和Clustering Key的區別
相同點:
Bitmap和Clustering Key都是檔案內的資料過濾。
不同點:
Bitmap更適合等值查詢,通過檔案號定位到資料;Clustering Key是檔案內的排序,因此更適合範圍查詢。
Clustering Key的優先順序會比Bitmap更高,即如果為同一個欄位設定了Clustering Key和Bitmap,那麼最佳化器會優先使用Clustering Key去匹配檔案,樣本如下:
V2.1版本起支援的文法:
--設定uid,class,date 3列為clustering key,text列設定預設為bitmap CREATE TABLE ck_bit_test ( uid int NOT NULL, name text NOT NULL, class text NOT NULL, date text NOT NULL, PRIMARY KEY (uid) ) WITH ( clustering_key = 'uid,class,date', bitmap_columns = 'name,class,date' ); INSERT INTO ck_bit_test VALUES (1,'張三','1','2022-10-19'), (2,'李四','3','2022-10-19'), (3,'王五','2','2022-10-20'), (4,'趙六','2','2022-10-20'), (5,'孫七','2','2022-10-18'), (6,'周八','3','2022-10-17'), (7,'吳九','3','2022-10-20');
所有版本支援的文法:
--設定uid,class,date 3列為clustering key,text列設定預設為bitmap begin; create table ck_bit_test ( uid int not null, name text not null, class text not null, date text not null, PRIMARY KEY (uid) ); call set_table_property('ck_bit_test', 'clustering_key', 'uid,class,date'); call set_table_property('ck_bit_test', 'bitmap_columns', 'name,class,date'); commit; INSERT INTO ck_bit_test VALUES (1,'張三','1','2022-10-19'), (2,'李四','3','2022-10-19'), (3,'王五','2','2022-10-20'), (4,'趙六','2','2022-10-20'), (5,'孫七','2','2022-10-18'), (6,'周八','3','2022-10-17'), (7,'吳九','3','2022-10-20');
查詢
uid,class,date
三列,SQL符合左匹配特徵,都命中Clustering Key,即使是等值查詢也走Clustering Key,而不是走Bitmap。SELECT * FROM clustering_test WHERE uid = '3' AND class ='2' AND date > '2022-10-17';
如下所示執行計畫結果中有
Cluster Filter
運算元,沒有Bitmap Filter
運算元,說明查詢走Clustering Key,而不是走Bitmap。查詢
uid,class,date
三列,但class
是範圍查詢,根據左匹配原則,SQL裡匹配到>
或者<
則停止左匹配,那麼date
因不滿足左匹配原則,就不會命中Clustering Key。date
設定了Bitmap,則會使用Bitmap。SELECT * FROM clustering_test WHERE uid = '3' AND class >'2' AND date = '2022-10-17';
如下所示執行計畫結果中有
Cluster Filter
運算元,說明查詢uid,class
走走Clustering Key;有Bitmap Filter
運算元,說明查詢date
走Bitmap。
使用樣本
V2.1版本起支援的文法:
CREATE TABLE tbl ( a text NOT NULL, b text NOT NULL ) WITH ( bitmap_columns = 'a:on,b:off' ); -- 修改bitmap_columns ALTER TABLE tbl SET (bitmap_columns = 'a:off');--ALTER TABLE文法僅支援全量修改
所有版本支援的文法:
--建立tbl並設定bitmap索引 begin; create table tbl ( a text not null, b text not null ); call set_table_property('tbl', 'bitmap_columns', 'a:on,b:off'); commit; --修改bitmap索引 call set_table_property('tbl', 'bitmap_columns', 'a:off');--全量修改,將a欄位的bitmap都關閉 call update_table_property('tbl', 'bitmap_columns', 'b:off');--增量修改,將b欄位的bitmap關閉,a保留