全部產品
Search
文件中心

Hologres:位元影像索引Bitmap

更新時間:Jun 30, 2024

本文為您介紹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屬性僅支援設為onoff,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。執行計畫2

    • 查詢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。執行計畫3

使用樣本

  • 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保留