订阅更新

前缀索引只有36字节?——Doris索引机制深度解析和调优

Doris手册 第 14 题 约 4 分钟读完

本文目录
  1. 先说结论
  2. 前缀索引(Short Key Index)——自动生效但有限制
  3. Key列顺序设计——影响前缀索引效果的核心
  4. Bloom Filter索引——高基数列的等值查询利器
  5. Bitmap索引——低基数列的过滤加速
  6. 三种索引的选型决策表
  7. 实战踩坑:给高基数列建Bitmap索引反而变慢
  8. 面试高频追问
  9. 总结

先说结论

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列顺序决定前缀索引效果——最常查询的小字节列放最前面。

刷题进度保存在当前浏览器