本文為您介紹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保留
相關文檔
關于Hologres內部表DDL語句的介紹詳情,請參見: