全部產品
Search
文件中心

Lindorm:倉模式列存表

更新時間:May 22, 2026

倉模式列存表(Warehouse Column Store Table)是 OLAP 資源群組的內建分析型資料表,採用列式儲存與 MPP 分布式執行架構,面向大規模離線與即時分析情境設計。倉模式列存表的資料完全託管於 OLAP 資源群組內部,與湖模式列存資料(lindorm_columnar)和寬表引擎資料(lindorm_table)相互獨立,具備完整的 DDL/DML 能力和高效能 OLAP 計算能力。

串連 OLAP 資源群組後,通過以下語句切換至倉模式列存表資料來源:

SET CATALOG default_catalog;

表類型

倉模式列存表根據寫入模型的不同分為兩種類型:明細表和主鍵表。表類型在建表時確定,建表後不可修改。 資料匯入時,系統依據表類型對匯入資料進行相應的排序、處理和儲存。

明細表

明細表(Duplicate Key Table)是倉模式列存表的預設表類型,採用追加寫入(Append-Only)資料模型。資料寫入時系統不做任何去重或彙總處理,允許排序鍵相同的資料行並存,完整保留每一條匯入記錄。

適用情境

  • 原始日誌、行為事件、埋點資料等不需要更新的明細流水分析

  • 同一資料集需要從多個維度靈活彙總,不希望受預彙總結構限制

  • 需要保留完整歷史快照,按任意條件精確召回未經處理資料

不適用情境:如果業務資料存在頻繁的更新或刪除需求(如訂單狀態變更、使用者資訊修改),應使用主鍵表。

建表文法

-- 樣本:使用者行為事件明細表
-- 按 (event_day, event_type) 排序:加速按日期和事件類型過濾的查詢
-- 按 user_id 雜湊分桶:保證同一使用者的資料集中在同一分桶,加速使用者維度 JOIN
CREATE TABLE user_event_log (
    event_day   DATE        NOT NULL COMMENT "事件日期",
    event_type  TINYINT     NOT NULL COMMENT "事件類型(1=點擊 2=曝光 3=轉化)",
    user_id     BIGINT      NOT NULL COMMENT "使用者ID",
    item_id     BIGINT               COMMENT "內容/商品ID",
    session_id  VARCHAR(64)          COMMENT "會話ID",
    duration_ms INT                  COMMENT "停留時間長度(毫秒)",
    province    VARCHAR(32)          COMMENT "省份",
    channel     VARCHAR(32)          COMMENT "來源渠道"
)
DUPLICATE KEY(event_day, event_type)
PARTITION BY date_trunc('day', event_day)
DISTRIBUTED BY HASH(user_id);

注意事項

  • 支援通過 ORDER BY 替代 DUPLICATE KEY 指定排序鍵,語義等價;若兩者同時出現,DUPLICATE KEY 不生效。使用 ORDER BY 時,該子句須放在 DISTRIBUTED BY 之後

  • 若排序鍵和分桶鍵均未指定,系統預設取前三列作為排序鍵。

  • 明細表支援為所有列建立 Bitmap 索引、Bloom Filter 索引,無需區分 Key/Value 列。

  • 明細表不支援 UPDATE 和 DELETE DML 語句(主鍵表支援)。

  • 如果匯入兩行完全相同的資料,明細表會將其視為獨立的兩行儲存,不會自動去重

資料模型

明細表將所有寫入資料按排序鍵進行物理排序後儲存於列式檔案中。每條記錄獨立存在,寫入後不可原地修改。資料檔案在後台非同步進行 Compaction(合并小檔案、回收空間),但不會對資料內容做任何去重或變更。

這種模型的核心優勢在於寫入吞吐高、靈活性強:寫入路徑沒有 Merge 或 Dedup 開銷,適合高頻追加情境;查詢側可以按任意維度自由彙總,不受預定義彙總結構的約束。

排序鍵設計

通過 DUPLICATE KEY 或 ORDER BY 聲明排序鍵,排序鍵決定資料的實體儲存體順序,同時作為首碼索引(Shortkey Index)的構建依據。

排序鍵設計原則:

  • 將最高頻的過濾列排在最前面:首碼索引只對排序鍵的連續首碼有效,最頻繁過濾的列應排在第一位。

  • 優先使用低基數列:低基數列(如日期、事件類型、城市)作為排序鍵首碼,可使相同值的行聚集儲存,配合 ZoneMap 索引大幅減少 I/O。

  • 高基數列(如 user_id、device_id)不適合置於排序鍵首碼:這類列值離散,排序鍵過濾效果差,建議用作 Bloom Filter 索引列或分桶鍵。

  • 排序鍵列數建議不超過 3 列:超過 36 位元組後首碼索引不再擴充,過多列對效能提升有限。


主鍵表

主鍵表(Primary Key Table)對主鍵列強制唯一非空約束,是專為即時資料更新高效能即席查詢並重情境設計的儲存模型。

適用情境

  • 通過 CDC 工具(如 Flink CDC)即時同步 MySQL、PostgreSQL 等事務型資料庫的全量增刪改變更

  • 電商訂單狀態追蹤、使用者畫像即時更新、物流運單狀態同步等高頻 UPSERT 情境

  • 多路資料流合并寫入同一張寬表,不同資料來源分別更新各自負責的列(部分列更新)

  • 需要對最新快照資料進行高並發複雜分析查詢

建表文法

-- 樣本:電商訂單即時分析表
-- 主鍵列 order_id、dt 須定義在最前面;分區列 dt 和分桶列 order_id 均須包含在主鍵中
-- ORDER BY (dt, merchant_id) 加速按日期和商戶維度範圍分析
-- 開啟持久化主鍵索引,避免巨量資料量下主鍵索引佔滿記憶體
CREATE TABLE orders (
    order_id       BIGINT         NOT NULL COMMENT "訂單ID",
    dt             DATE           NOT NULL COMMENT "下單日期",
    merchant_id    INT            NOT NULL COMMENT "商戶ID",
    user_id        BIGINT         NOT NULL COMMENT "使用者ID",
    good_id        INT            NOT NULL COMMENT "商品ID",
    good_name      VARCHAR(128)   NOT NULL COMMENT "商品名稱",
    total_amount   DECIMAL(18, 2) NOT NULL COMMENT "訂單金額",
    payment_amount DECIMAL(18, 2)          COMMENT "實付金額",
    status         TINYINT        NOT NULL COMMENT "訂單狀態",
    create_time    DATETIME       NOT NULL COMMENT "建立時間",
    update_time    DATETIME                COMMENT "最後更新時間"
)
PRIMARY KEY (order_id, dt)
PARTITION BY date_trunc('day', dt)
DISTRIBUTED BY HASH(order_id)
ORDER BY (dt, merchant_id);

注意事項

  • 主鍵列具有唯一非空約束;主鍵列不支援 DECIMAL 類型;主鍵總長度不得超過 128 位元組。

  • 建表時主鍵列必須連續置於列定義最前面:主鍵列須排在 CREATE TABLE 所有列定義的最前面,且主鍵列之間不能穿插非主鍵列,否則建表報錯。

  • 使用分區和雜湊分桶時,主鍵必須包含分區列和分桶列,以保證系統能精確定位目標資料分割和分桶執行更新。

  • 主鍵列的值不可更新UPDATE 只能修改非主鍵列;若必須變更主索引值,須先 DELETE 再 INSERT

  • 排序鍵(ORDER BY)與主鍵完全解耦,可獨立設計為任意列組合;排序鍵支援建表後修改ALTER TABLE tbl ORDER BY ...),但不支援刪除排序鍵,也不支援修改排序列的資料類型。

  • 主鍵表支援完整 DML:INSERTUPDATE(支援按 Key 列或 Value 列過濾)、DELETE(支援按 Key 列或 Value 列過濾)。

  • 主鍵表僅支援雜湊分桶,不支援隨機分桶。

寫入機制:Delete+Insert

主鍵表採用 Delete+Insert 寫入策略,區別於傳統的 Merge-On-Read(讀時合并)模型:

  • 寫入時:系統通過主鍵索引定位舊資料行,將其標記刪除,再寫入新資料行,同時更新主鍵索引。

  • 查詢時:資料已處於最終狀態,無需線上合并多版本,查詢直接讀取有效行。

這一機制使得主鍵表的查詢效能顯著優於 Merge-On-Read 模型,尤其在高更新頻率情境下,讀取放大問題被徹底消除。

主鍵設計原則

  • 主鍵應唯一標識業務實體:選取能全域唯一確定一條記錄的欄位組合,如 order_id(user_id, event_id)

  • 主鍵必須包含分區列和分桶列:使用分區(PARTITION BY)和雜湊分桶(DISTRIBUTED BY HASH)時,主鍵須涵蓋分區列和分桶列,以保證系統能精確定位目標資料分割和分桶執行更新。

  • 保持主鍵精簡:主鍵總位元組長度不得超過 128 位元組,列數建議不超過 3 列。優先選用 INTBIGINT 等佔用記憶體小的類型,避免使用 VARCHAR;主鍵列過多會增加索引儲存和維護開銷。

  • 主鍵列不支援 DECIMAL 類型:可使用 BIGINTVARCHAR 等常見類型。

  • 主鍵列不可為 NULL:所有主鍵列均須聲明 NOT NULL

排序鍵與主鍵解耦

主鍵(PRIMARY KEY)定義唯一性限制式,排序鍵(ORDER BY)定義資料的實體儲存體順序,兩者完全解耦,可獨立設計。

  • 排序鍵列可以是任意列的排列組合,不要求包含主鍵列,以查詢最頻繁的過濾列為設計依據。

  • 若不指定 ORDER BY,系統預設使用主鍵列作為排序鍵。

  • 排序鍵支援建表後修改ALTER TABLE tbl ORDER BY (col1, col2, ...);但不支援刪除排序鍵,也不支援修改排序列的資料類型。

部分列更新

主鍵表支援部分列更新(Partial Column Update)模式,允許不同寫入方只攜帶需要更新的列,系統以主鍵為關聯鍵自動合并各列資料。這是多路資料流即時寫寬表的核心能力。

-- 樣本:啟用部分列更新,寫入時只更新 status 和 update_time 列
INSERT INTO orders (order_id, status, update_time)
VALUES (10001, 3, '2024-03-01 10:30:00');
-- 其餘列(如 total_amount、user_id 等)保持原值不變

資料分布

資料分布策略決定資料在叢集中的實體儲存體方式,合理設計分區和分桶策略,可實現查詢時的有效資料裁剪和叢集計算資源的充分利用。

倉模式列存表的資料分布採用兩級結構

表(Table)
  └── 分區(Partition)     ← 邏輯劃分,用於資料管理和查詢裁剪
        └── 分桶(Bucket)  ← 物理劃分,用於均勻分布和並行計算

分區

分區將表按分區鍵拆分為獨立的資料管理單元。查詢條件包含分區鍵時,引擎自動定位並僅掃描目標資料分割(分區裁剪),跳過無關分區,顯著減少 I/O。分區也是資料生命週期管理的基本單元,可通過 DROP PARTITION 快速刪除歷史分區,效率遠高於 DELETE 語句。

運算式分區(推薦)

基於 date_trunc() 函數運算式按時間粒紋自動建分區,無需預定義分區列表,系統按資料中的時間欄位動態建立,推薦用於時序資料情境。

-- 按天自動分區
PARTITION BY date_trunc('day', event_time)

-- 按月自動分區
PARTITION BY date_trunc('month', order_date)

Range 分區

按數值或日期列的連續區間劃分,適合時序資料按日/周/月管理。

PARTITION BY RANGE(event_day) (
    PARTITION p202401 VALUES LESS THAN ("2024-02-01"),
    PARTITION p202402 VALUES LESS THAN ("2024-03-01"),
    PARTITION p202403 VALUES LESS THAN ("2024-04-01")
)

List 分區

按列的離散枚舉值劃分,適合按地區、狀態等維度管理資料。

PARTITION BY LIST(region) (
    PARTITION p_east   VALUES IN ("shanghai", "jiangsu", "zhejiang"),
    PARTITION p_north  VALUES IN ("beijing", "tianjin", "hebei"),
    PARTITION p_south  VALUES IN ("guangdong", "fujian", "hainan")
)
注意 分區鍵僅支援日期類型(DATEDATETIME)和整數類型(INTBIGINT 等)。

分桶

分桶在分區內部將資料進一步均勻打散到多個實體儲存體單元(Bucket/Tablet),提升並行掃描能力。

雜湊分桶

按指定分桶鍵的雜湊值分配資料,相同分桶鍵的資料落入同一桶,有利於等值查詢和同鍵 Join(本地化 Join 零網路傳輸)。分桶鍵應選擇高基數查詢最頻繁的過濾/關聯列,避免資料扭曲。

-- 系統自動推算分桶數
DISTRIBUTED BY HASH(user_id)

-- 手動指定分桶數
DISTRIBUTED BY HASH(order_id) BUCKETS 32

隨機分桶

資料隨機分配至各桶,無需指定分桶鍵,寫入均勻,適合無固定查詢模式的明細寫入情境。明細表預設使用隨機分桶,主鍵表不支援隨機分桶。

DISTRIBUTED BY RANDOM
最佳實務 單個 Bucket 的資料量建議控制在 100 MB ~ 1 GB 之間。Bucket 過大導致並行度不足;Bucket 過多增加中繼資料調度開銷。避免過細的分區(如按小時),大量小分區會顯著增加中繼資料壓力。

綜合樣本

-- 儲值明細表:按天運算式分區,按 user_id 雜湊分桶
CREATE TABLE recharge_detail (
    id             BIGINT         NOT NULL COMMENT "流水ID",
    user_id        BIGINT         NOT NULL COMMENT "使用者ID",
    recharge_money DECIMAL(18, 2) NOT NULL COMMENT "儲值金額",
    city           VARCHAR(32)    NOT NULL COMMENT "城市",
    dt             DATE           NOT NULL COMMENT "儲值日期"
)
DUPLICATE KEY(id)
PARTITION BY date_trunc('day', dt)
DISTRIBUTED BY HASH(user_id);

資料類型

數實值型別

類型

位元組

取值範圍

BOOLEAN

1

TRUE / FALSE

TINYINT

1

-128 ~ 127

SMALLINT

2

-32,768 ~ 32,767

INT

4

-2,147,483,648 ~ 2,147,483,647

BIGINT

8

-2⁶³ ~ 2⁶³-1

LARGEINT

16

-2¹²⁷ ~ 2¹²⁷-1,適用於超大整數(如 128 位裝置ID)

FLOAT

4

單精確度浮點,近似值

DOUBLE

8

雙精確度浮點,近似值

DECIMAL(M, D)

可變

精確小數,M 為總位元(最大 38),D 為小數位元,推薦金融/交易情境

注意 數實值型別不支援 UNSIGNED 修飾符。

字串類型

類型

最大長度

說明

CHAR(N)

255 位元組

定長字串,不足長度以空格補齊

VARCHAR(N)

1,048,576 位元組

變長字串,按實際長度儲存

STRING

同 VARCHAR

等同於大容量 VARCHAR,適合非結構化文本

日期時間類型

類型

說明

DATE

日期,格式 YYYY-MM-DD,範圍 0000-01-01 ~ 9999-12-31

DATETIME

日期時間,格式 YYYY-MM-DD HH:MM:SS[.ffffff],支援微秒精度

OLAP 專有類型

類型

說明

BITMAP

位元影像類型,配合 BITMAP_UNION 實現精確去重(如 UV 計算)

HLL

HyperLogLog 類型,配合 HLL_UNION 實現近似去重,誤差率約 1%,記憶體佔用極低

BITMAP 和 HLL 類型不能用作排序鍵列或主鍵列。

半結構化類型

類型

說明

JSON

彈性 JSON 文檔,支援路徑查詢(JSON_QUERY-> 操作符),適合 Schema 動態變化的情境

ARRAY<T>

同類型元素數組,支援 array_aggarray_containsarray_length 等數組函數

MAP<K, V>

索引值對映射,適合儲存動態屬性、標籤等 Schema 不固定的資料

STRUCT<field: type>

嵌套結構體,支援按欄位名訪問,適合多級嵌套資料建模


計算特性

SQL 分析運算元

倉模式列存表支援標準 SQL 分析文法,全面覆蓋 OLAP 情境下的分析計算需求。

投影與過濾

SELECT 支援對指定列進行投影,列名可設定別名(AS)、參與算術運算式或Function Compute。WHERE 子句支援多條件組合謂詞:

謂詞類型

樣本

等值過濾

status = 1

範圍過濾

amount BETWEEN 100 AND 1000dt >= '2024-01-01'

集合過濾

city IN ('beijing', 'shanghai')type NOT IN (3, 5)

模糊比對

name LIKE '張%'

NULL 判斷

pay_time IS NULLremark IS NOT NULL

正則過濾

email REGEXP '^[a-zA-Z0-9]+'

謂詞在執行時儘可能下推至儲存層,減少資料讀取量。

串連查詢(JOIN)

支援以下連線類型:

JOIN 類型

說明

INNER JOIN

返回兩表的匹配行

LEFT OUTER JOIN

保留左表所有行,右表無匹配則填 NULL

RIGHT OUTER JOIN

保留右表所有行,左表無匹配則填 NULL

FULL OUTER JOIN

保留兩表所有行

CROSS JOIN

笛卡爾積

LEFT SEMI JOIN

僅返回左表中在右表有匹配的行,不返回右表列

LEFT ANTI JOIN

僅返回左表中在右表無匹配的行

執行層根據表大小和資料分布自動選擇最優 Join 策略:小表廣播至所有節點(Broadcast Join)、資料按 Join 鍵重分布(Shuffle Join),或當分桶鍵與 Join 鍵一致時執行本地化 Join(零網路傳輸)。

-- 樣本:訂單明細與使用者畫像 JOIN
SELECT
    o.order_id,
    o.total_amount,
    u.user_level,
    u.city
FROM orders o
INNER JOIN user_profile u ON o.user_id = u.user_id
WHERE o.dt >= '2024-01-01'
  AND u.user_level IN ('gold', 'platinum');

集合運算

運算子

說明

UNION ALL

合并多個查詢結果,保留重複行,效能更優

UNION

合并多個查詢結果並去重

INTERSECT

返回兩個結果集的交集

EXCEPT / MINUS

返回在第一個結果集中但不在第二個中的行

分組彙總(GROUP BY)

支援標準彙總函式(COUNTSUMAVGMINMAXCOUNT DISTINCT)以及通過 HAVING 對彙總結果二次過濾。

支援以下擴充彙總文法,一次掃描完成多維度匯總,效能顯著優於多次獨立彙總查詢:

-- GROUPING SETS:顯式指定多組維度組合
SELECT city, dt, SUM(amount) AS total
FROM orders
GROUP BY GROUPING SETS ((city, dt), (city), ());

-- ROLLUP:層級匯總(從細粒度到總計)
-- 等價於 GROUPING SETS ((city, dt), (city), ())
SELECT city, dt, SUM(amount) AS total
FROM orders
GROUP BY ROLLUP (city, dt);

-- CUBE:對所有維度全量組合匯總
-- 等價於 GROUPING SETS ((city, dt), (city), (dt), ())
SELECT city, dt, SUM(amount) AS total
FROM orders
GROUP BY CUBE (city, dt);

排序與分頁

支援 ORDER BY 多列排序(ASC / DESC),配合 LIMIT 和 OFFSET 實現分頁查詢。

SELECT order_id, total_amount
FROM orders
WHERE dt = '2024-03-01'
ORDER BY total_amount DESC, order_id ASC
LIMIT 20 OFFSET 40;

子查詢

支援以下子查詢形式,最佳化器自動將可轉換的子查詢改寫為等價 JOIN 執行:

子查詢類型

樣本

標量子查詢

WHERE amount > (SELECT AVG(amount) FROM orders)

IN / NOT IN 子查詢

WHERE user_id IN (SELECT user_id FROM vip_users)

EXISTS / NOT EXISTS 子查詢

WHERE EXISTS (SELECT 1 FROM blacklist WHERE ...)

相互關聯的子查詢

子查詢引用外層查詢的列,逐行計算

視窗函數(Window Function)

視窗函數在保留原始行的同時對資料分組計算,是 OLAP 分析的核心能力。通過 OVER (PARTITION BY ... ORDER BY ... ROWS/RANGE ...) 文法定義計算視窗。

函數類別

常用函數

次序函數

ROW_NUMBER()RANK()DENSE_RANK()NTILE(n)

彙總分析

SUM()AVG()MIN()MAX()(支援滑動視窗)

位移訪問

LAG(col, n, default)LEAD(col, n, default)

首尾取值

FIRST_VALUE(col)LAST_VALUE(col)

-- 樣本:計算每個使用者的累計消費金額與當日消費排名
SELECT
    user_id,
    order_id,
    dt,
    total_amount,
    SUM(total_amount) OVER (
        PARTITION BY user_id
        ORDER BY dt
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS cumulative_amount,
    RANK() OVER (
        PARTITION BY dt
        ORDER BY total_amount DESC
    ) AS daily_rank
FROM orders;

-- 樣本:計算使用者相鄰兩次購買的間隔天數
SELECT
    user_id,
    order_id,
    dt,
    DATEDIFF(dt, LAG(dt, 1) OVER (PARTITION BY user_id ORDER BY dt)) AS days_since_last_order
FROM orders;

CASE WHEN 條件運算式

支援搜尋式和簡單式兩種文法,可在 SELECTWHEREORDER BY、彙總函式等任意位置使用。

SELECT
    order_id,
    total_amount,
    CASE
        WHEN total_amount >= 10000 THEN '大額'
        WHEN total_amount >= 1000  THEN '中額'
        WHEN total_amount >= 100   THEN '小額'
        ELSE '微額'
    END AS amount_tier,
    SUM(CASE WHEN status = 1 THEN total_amount ELSE 0 END) AS paid_amount
FROM orders
GROUP BY order_id, total_amount;

索引

倉模式列存表內建多層索引體系,各類索引協同工作,在不同查詢情境下發揮過濾和加速效果。

首碼索引(Shortkey Index)

系統自動建立,每 1024 行取排序鍵首碼(不超過 36 位元組、不超過 3 列)儲存一條稀疏索引項目。查詢中帶有排序鍵首碼過濾條件時,引擎通過二分尋找快速定位目標資料區塊,無需手動建立。

觸發條件:查詢過濾條件必須能構成排序鍵的首碼

排序鍵:(event_day, site_id, city_code)

✅ WHERE event_day = '2024-01-01'                       -- 命中首碼索引
✅ WHERE event_day = '2024-01-01' AND site_id = 10      -- 命中首碼索引
❌ WHERE city_code = 'BJ'                               -- 不構成首碼,無法使用
建表時應將查詢最高頻的過濾列排在排序鍵最前面,使其優先被首碼索引覆蓋。

ZoneMap 索引

系統自動為每列的每個資料區塊(Page,預設 64 KB)維護最小值(Min)、最大值(Max)和 NULL 存在性統計,無需手動建立。執行範圍查詢時,引擎通過比對各 Page 的 Min/Max 快速跳過不滿足條件的 Page,實現資料區塊層級的高效裁剪。

適用情境:數值、日期等有序類型列上的範圍過濾(BETWEEN><>=<=)。

Bloom Filter 索引

基於 Bloom Filter 演算法,以資料區塊(Page)為粒度構建跳數索引。寫入時對每個 Page 中的列值計算雜湊寫入 Bloom Filter;查詢時對過濾條件值計算雜湊並判斷是否存在,不存在則直接跳過該 Page,從而減少 I/O。

適用情境:高基數列(如使用者ID、訂單ID、裝置碼)的等值查詢=IN)。此類列基數過高,不適合 Bitmap 索引(儲存開銷過大)。

通過 PROPERTIES 中的 bloom_filter_columns 參數指定,建表後支援通過 ALTER TABLE 動態變更。

-- 建表時建立
CREATE TABLE orders (
    order_id    BIGINT         NOT NULL,
    user_id     BIGINT         NOT NULL,
    merchant_id INT            NOT NULL,
    dt          DATE           NOT NULL,
    amount      DECIMAL(18, 2)
)
PRIMARY KEY(order_id)
DISTRIBUTED BY HASH(order_id)
PROPERTIES (
    "bloom_filter_columns" = "user_id, merchant_id"
);

-- 建表後動態添加
ALTER TABLE orders SET ("bloom_filter_columns" = "user_id, merchant_id, dt");

-- 刪除 Bloom Filter 索引
ALTER TABLE orders SET ("bloom_filter_columns" = "");

注意事項

  • 不支援 TINYINTFLOATDOUBLEDECIMAL 類型列。

  • 僅對等值查詢有效,範圍查詢(><BETWEEN)無效。

  • 不適用於低基數列(應使用 Bitmap 索引)。

Bitmap 索引

為列的每個唯一值建立一個位元影像(每位對應表中一行,0/1 表示該行是否含有該值)。多條件查詢時,通過對多個位元影像執行位元運算(AND/OR/NOT)高效得到結果集,內部使用 Roaring Bitmap 壓縮結構,儲存空間相較傳統位元影像最高節省 90%。

適用情境:中等基數列(建議基數在 10,000 ~ 100,000 之間)的等值查詢,以及多列組合過濾(如使用者畫像中同時按年齡段、消費等級、城市過濾)。

通過 INDEX 子句定義,或建表後通過 CREATE INDEX 動態添加(屬於非同步 Schema Change 操作)。

-- 建表時建立 Bitmap 索引
CREATE TABLE user_profile (
    user_id      BIGINT      NOT NULL COMMENT "使用者ID",
    age_range    TINYINT              COMMENT "年齡段(1-5)",
    gender       TINYINT              COMMENT "性別(0=女,1=男)",
    city_code    VARCHAR(20)          COMMENT "城市編碼",
    user_level   TINYINT              COMMENT "使用者等級(1-5)",
    register_day DATE                 COMMENT "註冊日期",
    INDEX idx_age_range  (age_range)  USING BITMAP COMMENT "年齡段索引",
    INDEX idx_city_code  (city_code)  USING BITMAP COMMENT "城市索引",
    INDEX idx_user_level (user_level) USING BITMAP COMMENT "等級索引"
)
DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id);

-- 建表後動態添加
CREATE INDEX idx_gender ON user_profile (gender) USING BITMAP;

-- 查看索引
SHOW INDEX FROM user_profile;

-- 刪除索引
DROP INDEX idx_gender ON user_profile;

注意事項

  • 不支援 FLOATDOUBLEBOOLEANDECIMAL 類型列。

  • 基數過高(超過 100 萬)時,Bitmap 索引儲存膨脹,應改用 Bloom Filter 索引。

  • 若索引過濾比例低(如篩選超過 50% 的資料),索引收益為負,不建議建立。

索引選型參考

查詢情境

推薦索引

排序鍵首碼列的等值/範圍查詢

首碼索引(自動,無需建立)

數值/日期列的範圍過濾

ZoneMap 索引(自動,無需建立)

中等基數列的等值過濾、多列組合過濾

Bitmap 索引

高基數列(ID類)的等值過濾

Bloom Filter 索引