前缀索引只有36字节?——Doris索引机制深度解析和调优
本文目录
先说结论
Doris有三类索引机制:前缀索引(Short Key Index,自动创建,基于Key列前缀)、Bloom Filter索引(手动开启,高基数列的等值查询加速)、Bitmap索引(手动创建,低基数列的过滤加速)。选错索引类型不仅没效果,还浪费存储空间和写入性能。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
第3篇粗略讲了Doris的三种索引,这篇深入讲索引的内部原理和调优技巧。在某元宇宙社交公司,有一次按device_id查询特别慢,加了Bloom Filter索引后查询速度提升了5倍。但很多人不知道Bloom Filter有误判率、前缀索引有36字节限制、Bitmap索引只适合低基数列。索引用错了比不用还差。
前缀索引(Short Key Index)——自动生效但有限制
36字节限制的实战影响:如果Key列第一个字段是VARCHAR(256),前缀索引只覆盖前36字节,后面的Key列完全不在索引里。所以Key列排列原则:字节数小的列放前面(INT 4字节、BIGINT 8字节、DATE 3字节),VARCHAR大字段放后面。
Key列顺序设计——影响前缀索引效果的核心
| 设计 | 前缀索引覆盖 | 常见查询是否命中 |
|---|---|---|
| KEY(event_time, user_id) | event_time(8)+user_id(8)=16字节 | WHERE event_time=xxx 命中 |
| KEY(user_id, event_time) | user_id(8)+event_time(8)=16字节 | WHERE user_id=xxx 命中 |
| KEY(country, event_time) | country(截断)+event_time 在36字节内 | WHERE country=xxx 命中 |
| KEY(description, user_id) | description占满36字节! | user_id根本不在索引里 |
Bloom Filter索引——高基数列的等值查询利器
Bitmap索引——低基数列的过滤加速
三种索引的选型决策表
| 场景 | 推荐索引 | 原因 |
|---|---|---|
| 按时间范围查 | 前缀索引(dt放Key首位) | 前缀索引支持范围查询 |
| 按user_id等值查 | 前缀索引+Bloom Filter | 前缀索引命中+BF跳过无关块 |
| 按device_id等值查 | Bloom Filter | 高基数列,BF效果最好 |
| 按country过滤 | Bitmap索引 | 低基数列,Bitmap效率高 |
| 按status过滤 | Bitmap索引 | 极低基数,Bitmap最合适 |
| 按amount范围查 | 无特殊索引 | 连续数值范围查,索引帮助有限 |
实战踩坑:给高基数列建Bitmap索引反而变慢
在某元宇宙社交公司,我给user_id列建了Bitmap索引(以为Bitmap对所有列都有效)。结果WHERE user_id = 123不仅没变快,反而慢了20%。
原因:user_id有几百万个不同值,每个值的Bitmap非常稀疏,但Bitmap索引文件变得巨大(几个GB),加载和解析Bitmap本身就很耗时。
修复:删掉Bitmap索引,改用Bloom Filter索引。BF索引文件小得多(几十MB),等值查询速度提升了5倍。
教训:高基数列用Bloom Filter,低基数列用Bitmap。反过来用效果很差甚至有负面影响。建索引前一定要分析列的基数。
面试高频追问
追问一:Bloom Filter的误判率能调吗?
可以。通过bloom_filter_fpp参数设置,默认0.05(5%)。设得越低误判越少但索引文件越大。一般不建议调——默认5%已经够用了。
追问二:前缀索引的36字节限制能突破吗?
不能直接突破,但有替代方案:① 调整Key列顺序;② 用Bloom Filter或Bitmap辅助;③ 创建Rollup,Rollup可以有不同的Key列顺序,相当于另一套前缀索引。
追问三:索引会影响写入性能吗?
会。前缀索引影响最小;Bloom Filter有一定开销;Bitmap索引开销最大。不要给不常查的列加索引。
总结
Doris索引面试讲三类索引的原理和适用场景:前缀索引(自动、Key前缀、36字节限制)、Bloom Filter(高基数等值查询、有误判率)、Bitmap(低基数过滤、位图运算)。核心踩坑:高基数列不要用Bitmap,低基数列不要用Bloom Filter。Key列顺序决定前缀索引效果——最常查询的小字节列放最前面。