StarRocks 各类索引以及存储位置详解
StarRocks 支持多种索引机制,不同索引根据其功能和设计目标,存储在不同的层级和位置。以下是 主键索引、前缀索引、Ordinal 索引、ZoneMap 索引、Bloom Filter、Bitmap 索引 的详细存储位置对比。
结论
索引类型 | 存储位置 | 存储层级 | 是否独立文件 | 是否可持久化 |
---|---|---|---|---|
主键索引 (Primary Key Index) | persistent_index/ 目录下的 .pkindex 文件 | Tablet 级(全局) | ✅ 独立 | ✅ 是(推荐) |
前缀索引 (Prefix Index) | segment_xxx.idx 文件 | Segment 级 | ✅ 附属文件 | ✅ 是 |
Ordinal 索引 | 内嵌于 .idx 文件或段元数据中 | Segment 级 | ❌ 否(内嵌) | ✅ 是 |
ZoneMap 索引 | segment_xxx.idx 文件(与前缀索引共存) | Segment 级 | ✅ 附属文件 | ✅ 是 |
Bloom Filter 索引 | col_<column>.bloom 文件 | Segment 级 | ✅ 附属文件 | ✅ 是 |
Bitmap 索引 | col_<column>.bitmap 文件 | Segment 级 | ✅ 附属文件 | ✅ 是 |
📌 所有索引在查询时均可加载到 BE 内存缓存 中以加速访问。
详细存储结构图
/starrocks/be/storage/data/0/<tablet_id>/
│
├── persistent_index/ ← 主键索引(独立全局)
│ └── primary_key.pkindex → RocksDB 格式,存储主键 → (RowSet, Segment, row_id) 映射
│
├── rowset_12345/ ← RowSet 1
│ ├── segment_001.dat → 数据文件
│ ├── segment_001.idx → 前缀索引 + ZoneMap + Ordinal 索引 ✅
│ ├── col_user_id.bloom → Bloom Filter ✅
│ └── col_status.bitmap → Bitmap 索引 ✅
│
├── rowset_67890/ ← RowSet 2
│ ├── segment_002.dat
│ ├── segment_002.idx → 前缀索引 + ZoneMap + Ordinal 索引 ✅
│ ├── col_user_id.bloom → Bloom Filter ✅
│ └── col_gender.bitmap → Bitmap 索引 ✅
│
🔍 各类索引存储详解
1. 主键索引 (Primary Key Index)
- 存储位置:
- ✅ 独立目录:
/starrocks/be/storage/data/0/<tablet_id>/persistent_index/
- ✅ 文件名:
primary_key.pkindex
(RocksDB SSTables)
- ✅ 独立目录:
- 存储层级:Tablet 级,覆盖所有 RowSet 和 Segment。
- 是否独立:✅ 是,不依赖任何 RowSet 或 Segment。
- 持久化:
- 必须启用:
"enable_persistent_index" = "true"
- 重启后无需重建,保障高可用。
- 必须启用:
- 内容:主键值 →
(RowSet ID, Segment ID, 行号)
的映射。
💡 作用:支持
UPSERT
、DELETE
,实现行级更新。
2. 前缀索引 (Prefix Index / ZoneMap)
- 存储位置:
- ✅ 每个 Segment 一个文件:
segment_xxx.idx
- 与
.dat
文件同目录。
- ✅ 每个 Segment 一个文件:
- 存储层级:Segment 级
- 是否独立:❌ 否,是 Segment 的附属索引文件。
- 持久化:✅ 是,随 Segment 持久化。
- 内容:每 1024 行的 min/max 值,用于数据块剪枝。
💡 作用:加速
WHERE col > 100
类范围查询,减少扫描量。
在实现上,可以作用于一个 Segment,也可以是一个列的一个 Data Page,相应的 ZoneMap 索引有两种:一种是存每个 Segment 的统计信息,另一种是存每个 Data Page 的统计信息
3. Bloom Filter 索引
- 存储位置:
- ✅ 每个启用了 BF 的列一个文件:
col_<column_name>.bloom
- 与 Segment 文件同目录。
- ✅ 每个启用了 BF 的列一个文件:
- 存储层级:Segment 级
- 是否独立:❌ 否,是列的附属索引。
- 持久化:✅ 是。
- 内容:列中所有值的哈希指纹(位数组),用于快速判断“某值是否存在”。
💡 作用:加速
WHERE user_id = '123'
类等值查询,避免无效 I/O。
4. Bitmap 索引
- 存储位置:
- ✅ 每个启用了 Bitmap 的列一个文件:
col_<column_name>.bitmap
- 与 Segment 文件同目录。
- ✅ 每个启用了 Bitmap 的列一个文件:
- 存储层级:Segment 级
- 是否独立:❌ 否。
- 持久化:✅ 是。
- 内容:低基数列(如
status
,gender
)的位图映射,支持IN
、=
查询的位运算。
💡 作用:高效处理
WHERE status IN ('PENDING', 'DONE')
类查询。
🔄 查询时的内存加载情况
索引类型 | 内存加载行为 |
---|---|
主键索引 | 常驻内存或缓存热数据 |
前缀索引 | 查询时加载到 Index Cache ,常驻内存 |
Bloom Filter | 查询时加载,高频列常驻内存 |
Bitmap 索引 | 查询时加载 |
⚠️ 主键索引内存占用较大,需根据主键列大小和行数规划 BE 内存。
如何配置和查看?
1. 建表时启用索引
CREATE TABLE user_table (user_id BIGINT status VARCHAR(20),gender VARCHAR(10),visit_time DATETIME,...
)
PRIMARY KEY (user_id)
DISTRIBUTED BY HASH(user_id)
PROPERTIES ("enable_persistent_index" = "true", -- 主键索引持久化"bloom_filter_columns" = "user_id", -- Bloom Filter"bitmap_columns" = "status,gender" -- Bitmap 索引
);