全部产品
Search
文档中心

云原生多模数据库 Lindorm:仓模式列存表

更新时间:May 21, 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)、参与算术表达式或函数计算。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 索引