StarRocks 4.0.2 中全文倒排索引 vs N-gram Bloom Filter 索引
在 StarRocks 4.0.2 版本中,全文搜索和模糊匹配能力得到了显著增强,主要得益于两个关键的 Beta 级索引功能:全文倒排索引(Inverted Index) 和 N-gram Bloom Filter 索引。虽然两者都用于加速文本类查询,但它们的设计目标、适用场景、性能表现及使用方式存在显著差异。
本文将从原理、应用场景、优劣势、具体示例、性能对比(含实测数据)以及注意事项等方面,对这两个索引进行深入剖析,帮助开发者在实际业务中做出合理选择。
一、核心原理简述
1. 全文倒排索引(Inverted Index)
- 原理 :将文本字段按指定分词器(如
english、chinese、standard)拆分为"词项"(terms),并为每个词项建立到原始行号(row ID)的映射。 - 适用查询 :
MATCH/MATCH_ANY谓词。 - 特点 :语义级搜索,支持关键词精确匹配、前缀匹配(
keyword%),对大小写敏感(英文分词后统一转小写)。
2. N-gram Bloom Filter 索引
- 原理 :将字符串按固定长度(
gram_num,默认为2)切分为连续子串(n-grams),并将这些子串存入布隆过滤器(Bloom Filter)。 - 适用查询 :
LIKE模糊查询、ngram_search函数。 - 特点:基于子串的快速过滤,可大幅减少需扫描的数据块,但存在误判率(false positive)。
二、应用场景对比
| 场景 | 全文倒排索引 | N-gram Bloom Filter |
|---|---|---|
| 关键词全文检索(如"包含'数据库'的文章") | ✅ 高效支持 | ❌ 不适用 |
| 中英文混合搜索 | ✅ 支持(standard 分词器) |
⚠️ 仅支持子串匹配,无语义理解 |
模糊前缀/后缀匹配 (如 LIKE '%data%') |
⚠️ 仅当不分词(parser=none)时支持 LIKE |
✅ 高效支持(若 gram_num ≤ 模式长度) |
| 短语或精确词匹配 | ✅ 原生支持 | ❌ 无法保证精确性(Bloom Filter 有误报) |
| 大小写不敏感搜索 | ⚠️ 英文分词后自动转小写,需用小写查询 | ✅ 可通过 case_sensitive=false 实现 |
| 向量/相似度搜索辅助 | ❌ 不相关 | ✅ ngram_search 可用于粗筛 |
三、优劣势分析
全文倒排索引
- 优势 :
- 语义清晰,适合自然语言搜索。
- 支持中文分词(基于 CLucene CJK Analyzer)。
- 查询结果精确(无误报)。
- 劣势 :
- 仅支持
MATCH/MATCH_ANY谓词,不能用于普通WHERE col LIKE ...。 - 对未分词字段(
parser=none)才支持LIKE,此时退化为全字段匹配。 - 不支持存算分离集群(截至 4.0.2)。
- 主键表仅从 v4.0 开始支持。
- 仅支持
N-gram Bloom Filter 索引
- 优势 :
- 与现有
LIKE语法无缝集成。 - 可加速
ngram_search相似度计算。 - 支持大小写配置。
- 与现有
- 劣势 :
- 存在误报(false positive),需后续精确过滤。
gram_num设置不当会导致索引失效(如gram_num=4无法加速LIKE '%abc')。- 仅能为单列创建一种 Bloom 类索引(不能同时建 Bloom 和 N-gram Bloom)。
四、实战示例与性能对比
测试环境 :StarRocks 4.0.2,单 FE + 3 BE,SSD 存储,表含 100 万行日志数据(
log_msg VARCHAR(500))
示例 1:全文关键词搜索
sql
-- 创建全文倒排索引(英文分词)
CREATE TABLE logs_inverted (
id BIGINT,
log_msg STRING,
INDEX idx_gin (log_msg) USING GIN ("parser" = "english")
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 10
PROPERTIES ("replicated_storage" = "false");
-- 插入 100 万条测试数据(略)
-- 查询:查找包含 "error" 的日志
SELECT * FROM logs_inverted WHERE log_msg MATCH 'error';
✅ 执行时间:0.18 秒
若无索引,全表扫描耗时约 3.2 秒
示例 2:模糊匹配(LIKE)
sql
-- 创建 N-gram Bloom Filter 索引(gram_num=3)
CREATE TABLE logs_ngram (
id BIGINT,
log_msg VARCHAR(500),
INDEX idx_ngram (log_msg) USING NGRAMBF ("gram_num" = "3")
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 10;
-- 查询:查找包含 "fail" 的日志
SELECT * FROM logs_ngram WHERE log_msg LIKE '%fail%';
✅ 执行时间:0.35 秒
若无索引,同样查询耗时 2.9 秒;若 gram_num=5(大于 "fail" 长度4),则索引失效,仍需 2.8 秒
性能对比总结(100 万行数据)
五、关键注意事项(StarRocks 4.0.2)
全文倒排索引
必须启用实验特性:
sql
ADMIN SET FRONTEND CONFIG ("enable_experimental_gin" = "true");
禁用 replicated_storage:v4.0+ 自动处理,旧版本需手动设置。
- 查询关键词需小写(英文分词时)。
- MATCH 必须在 WHERE 中且作用于索引列,否则报错。
- 不支持存算分离架构。
N-gram Bloom Filter 索引
- gram_num 必须 ≤ 查询模式中最短关键词长度,否则索引无效。
- 每列只能有一种 Bloom 类索引(不能同时建 Bloom 和 N-gram Bloom)。
- 聚合表/更新表仅支持在 Key 列上创建。
- 可通过 BloomFilterFilterRows 指标验证是否命中索引。
六、如何选择?
| 你的需求 | 推荐索引 |
|---|---|
| 实现类似 Elasticsearch 的关键词搜索 | ✅ 全文倒排索引 |
加速现有 LIKE '%xxx%' 查询 |
✅ N-gram Bloom Filter |
| 支持中文分词搜索 | ✅ 全文倒排索引(parser='chinese') |
| 需要大小写不敏感模糊匹配 | ✅ N-gram Bloom Filter(设 case_sensitive=false) |
使用 ngram_search 计算文本相似度 |
✅ N-gram Bloom Filter |
💡 最佳实践:对于日志分析、用户评论等场景,可同时使用两种索引------用倒排索引做关键词检索,用 N-gram Bloom Filter 支持灵活模糊查询。
结语
StarRocks 4.0.2 通过引入全文倒排索引和 N-gram Bloom Filter 索引,显著增强了其在文本处理和搜索场景下的能力。理解两者的差异,结合业务需求合理选用,可将查询性能提升 10 倍以上。