位图索引不支持数组变量作为查询条件,仅支持单值匹配、多值OR/AND及聚合;多值条件通过查各值位图后按位OR实现;因要求列值为原子标量,故无法对JSON数组等非标量列建有效位图索引。
位图索引本身不直接支持“数组变量”作为查询条件,它面向的是单值匹配、多值 or(如 where status in ('a','b'))、and(如多列位图联合过滤)或统计聚合场景。所谓“数组变量”的使用,实质是将应用层传入的多个离散值,转化为位图间的按位运算,而非在sql中直接传递一个数组类型参数。
位图索引如何处理多值条件
当查询涉及多个枚举值(例如:状态码 ['processed', 'pending', 'failed']),数据库会:
- 为每个值查出对应位图(如
bitmap_processed、bitmap_pending、bitmap_failed) - 执行按位 OR 运算:
bitmap_processed | bitmap_pending | bitmap_failed - 结果位图中为 1 的位置,即为满足任一条件的行号(RowID)
- 引擎据此快速定位物理数据块,跳过大量无关行
为什么不能把数组当字段值来建位图索引
位图索引要求被索引列是原子值(atomic value),即每行仅存一个确定的标量——比如 gender = 'female' 或 category_id = 5。若某列实际存储 JSON 数组、逗号分隔字符串(如 "1,3,7")或 PostgreSQL 的 INT[] 类型:
- 该列属于高 Cardinality 或非标量结构,不符合位图索引设计前提
- 即使强行创建(部分系统报错或静默降级),也无法生成有效位图:无法定义“哪个位对应哪个子元素”
- 查询时仍需先 unnest / string_to_array 解构,失去位图加速意义
真正提升分析效率的替代方案
面对含多值语义的业务需求(如“用户打标集合”“订单关联多个渠道”),推荐以下可落地做法:
-
规范化建模:拆分为关联表(如
user_tags(user_id, tag_id)),对tag_id单独建位图索引——这是最标准、最高效的方式 -
物化标签位图:预计算每个用户对应的标签位图(如用 Roaring Bitmap 库生成
user_bitmap字段),存为二进制或整数数组,查询时用 UDF 做位运算 -
向量化谓词下推:在 Doris / StarRocks / SelectDB 中,配合
BITMAP_CONTAINS函数与TO_BITMAP,实现类似“数组包含”的高效过滤 -
避免运行时解析:不使用
LIKE '%a%'或string_to_array(col,',') @> ARRAY['x']等无法走索引的操作
实战注意:性能拐点与限制
位图索引的加速效果并非线性增长,需警惕几个关键阈值:
- 被索引列唯一值数量 > 500 时,位图数量激增,空间和 OR 运算开销迅速上升
- 表总行数
- 更新频繁(日增删改 > 5% 行数)会导致位图重写成本高,锁粒度大,OLTP 场景慎用
- SelectDB / Doris 要求启用 Segment V2 格式,且仅对
REPLACE或UNIQUE模型中的明细列生效



















