索引
索引是 Lakehouse 减少数据扫描量、提升查询性能的机制,在数据文件内记录额外元数据,让查询引擎在文件级别快速过滤,不改变数据的物理存储方式。
选型指南
索引类型对比
| 索引类型 | 适用查询 | 适用列类型 | 典型场景 |
|---|---|---|---|
| Bloomfilter 索引 | 等值过滤(、) | 高基数列(用户 ID、订单号、设备 ID) | 按 ID 点查,跳过不包含目标值的数据文件 |
| 倒排索引 | 全文检索()、关键词匹配 | 文本列(STRING、VARCHAR) | 日志搜索、商品名称检索、JSON 字段过滤 |
| 向量索引 | 近似最近邻检索(ANN) | VECTOR 类型列 | 语义搜索、图像相似度、RAG 召回 |
选型规则:
- ID 类字段、状态码,等值查询多 → Bloomfilter 索引
- 文本内容,需要关键词或短语搜索 → 倒排索引
- 向量嵌入,需要语义相似度检索 → 向量索引
- 上述三类可以在同一张表上同时创建,互不冲突
核心机制
隐藏分区
Lakehouse 的分区类似 Apache Iceberg 的隐藏分区机制:
- 分区信息存储在元数据中,不需要在 SQL 查询时手动指定分区条件
- 支持转换分区函数(
/years
/months
/days
/hours
/bucket
),按时间维度自动分区truncate - 分区策略可以在不影响已有数据的情况下修改(Hive 的静态分区不支持这点)
Bloomfilter 工作原理
Bloomfilter 是一种概率数据结构,在数据文件级别记录列值的存在性:
- 某个值不存在:100% 准确,直接跳过该文件
- 某个值可能存在:需要实际读取验证(极低概率误判)
因此 Bloomfilter 只对等值查询有效,范围查询无法利用。
快速示例
常见问题
常见问题 1:对低基数列建 Bloomfilter 索引
问题:在性别、状态、枚举类列上创建 Bloomfilter 索引。
症状:查询性能几乎没有提升,但索引数据占用了额外存储。
解决:Bloomfilter 索引只对高基数列有效(如用户 ID、订单号)。低基数列考虑分区(如按状态分区)或直接全表扫描。
对已有大表建索引需要先 BUILD
问题:对已有数据的表用
ALTER TABLE ... ADD INDEX 添加索引后,旧数据无索引覆盖。
解决:添加索引后需执行
BUILD INDEX 对历史数据构建索引:
常见问题 3:分区粒度过细导致小文件过多
问题:数据量不大,但按小时分区(
hours(event_time))。
症状:查询元数据开销大,
SHOW PARTITIONS 返回大量分区,反而拖慢查询。
解决:分区粒度与数据量匹配——日数据量 GB 级用
days,TB 级可以考虑 hours。单个分区内数据量建议 128MB 以上。
成本影响
存储成本
- 索引数据存储在独立文件中,额外占用存储空间
- Bloomfilter 索引体积小(概率结构,通常 < 原数据 1%)
- 倒排索引体积较大(分词后建立词典,通常是原列数据的 20%-100%)
- 向量索引体积最大(HNSW 图结构,通常与原向量数据体积相当)
计算成本
消耗 VCluster CRU(一次性)BUILD INDEX- 索引构建完成后,查询时减少扫描量,降低 CRU 消耗
- 分区不产生额外计算成本,通过元数据裁剪减少 I/O
本章内容
| 页面 | 说明 |
|---|---|
| 索引概述 | 三种索引类型对比与选型建议 |
| Bloomfilter Index | 等值过滤加速,高基数列快速跳过文件 |
| 倒排索引 | 全文检索加速,MATCH 查询 |
| 索引最佳实践 | 多索引组合、AI 场景、运维建议 |
相关文档
| 文档 | 说明 |
|---|---|
| 表设计 | 分区和索引是建表时的核心设计决策 |
| BUILD INDEX | 对历史数据构建索引 |
| DROP INDEX | 删除索引 |
| SHOW INDEX | 查看表上的索引 |
联系我们
