You need to enable JavaScript to run this app.
导航
跳数索引
最近更新时间:2025.12.03 15:56:53首次发布时间:2024.12.10 17:49:33
复制全文
我的收藏
有用
有用
无用
无用

ByteHouse 企业版提供了一种二级索引——跳数索引,支持在建表后异步添加。该特性解决了排序索引仅能在建表时设置的局限,让索引调整更具灵活性,助力您更便捷地实现查询加速。本文将围绕跳数索引的基本概念与使用方法展开介绍。

适用场景

ByteHouse MergeTree 家族表引擎在建表阶段支持配置排序索引。当查询条件包含排序索引字段时,系统可预先过滤数据,减少 IO 消耗,以实现查询加速。但排序索引存在局限性,仅支持在建表时设置,建表后无法调整,灵活性不足。为此,ByteHouse 提供跳数索引这一二级索引类型,支持在建表后异步添加。它的原理与排序索引相近,同样是在字段上构建稀疏索引,从而在查询过程中实现部分数据裁剪。尽管跳数索引的查询加速效果不及排序索引,但凭借其灵活调整的特性,仍在实际场景中发挥着广泛作用。

索引类型

常用的跳数索引类型说明如下:

索引类型

说明

minmax

轻量级索引,无需设置额外的参数。minmax 用于存储每个数据块中索引表达式的最小值和最大值。如果表达式为元组(Tuple),则分别存储元组各元素的值。该类型适用于按值松散排序的列。minmax 索引通常是查询处理中应用成本最低的,但是仅适用于标量或元组表达式,不支持应用于返回数组或 Map 的表达式。

set

轻量级索引,用于存储数据块中的所有值,支持设置单个参数,即每个数据块的值集的最大大小。当该参数设置为 0 时,允许存储无限数量的离散值。如果数据块中值的数量超过该最大容量,索引将为空。
set 索引适用于每个数据颗粒内基数较低、但整体基数较高的列,其索引成本、查询性能及有效性取决于数据块内的基数。如果每个数据块包含大量唯一值,针对大型索引集评估查询条件的成本将会显著增加,或者由于值的数量超过最大容量而导致索引为空,此时 set 索引将无法生效。

Bloom Filter (布隆过滤器)

布隆过滤器是一种数据结构,可在允许轻微误报的前提下,实现高效的集合成员测试。由于布隆过滤器能更高效处理大量离散值的测试场景,因此,它适用于需匹配较多测试值的条件表达式,且支持应用于数组。基于布隆过滤器的跳数索引包含以下三种类型:

bloom_filter:支持设置允许的“误报率”,取值范围为 0~1。若未指定,默认值为 0.025,此参数为可选配置。

tokenbf_v1:仅适用于 String、FixedString 数据类型。该索引会将输入表达式按照非字母数字字符分隔为字符序列。例如,列值 "This is a candidate for a 'full text' search" 将被拆分为词条 This is a candidate for full text searchtokenbf_v1适用于 LIKE、EQUALS、IN、hasToken() 及类似搜索场景,可用于在较长字符串中搜索单词和其他值,支持设置三个参数:

  • 过滤器大小:以字节为单位,过滤器越大,误报率越低,但存储成本会相应增加;
  • 哈希函数数量:哈希函数数量越多,误报率越低;
  • 布隆过滤器哈希函数的种子值

ngrambf_v1:将字符串按固定长度分割为 ngram,例如,当 ngram 长度设为 4 时,字符串 "A short string with an ngram size of 4" 将被索引为: 'A sh'、' sho'、'shor'、'hort'、'ort '、'rt s'、't st'、' str'、'stri'、'trin'、'ring'。该索引同样适用于文本搜索场景,尤其对于没有单词间隔的语言,如中文。该索引支持设置四个参数:

  • ngram长度
  • 过滤器大小:以字节为单位,过滤器越大,误报率越低,但存储成本会相应增加;
  • 哈希函数数量:哈希函数数量越多,误报率越低;
  • 布隆过滤器哈希函数的种子值

除上述各跳数索引类型中提及的专属参数外,所有跳数索引均支持配置 GRANULARITY(索引粒度)参数,通常建议将 GRANULARITY 设为 1,以获取更高的数据过滤率;若调整 GRANULARITY 至更大数值,虽能减少索引的存储占用,但相应的数据过滤效果可能会随之减弱。当前该参数支持的配置范围为 1~10。

注意事项
  1. 使用跳数索引需依赖对数据分布的认知,更适用于高基数列场景,以及等值查询或小范围查询场景;不适用于基数较低的列场景,或查询条件会命中大范围数据的场景。
  2. 不同数据类型字段对应的跳数索引类型推荐优先级如下:
    • 针对数值类型字段,通常优先选用 minmax 索引或 bloom_filter 索引;
    • 针对 String 类型字段,可统一选用 bloom_filter 索引,建议配置误报率 0.1,即 bloom_filter(0.1),操作便捷高效;
    • 如果一定要在 LIKE 查询场景中使用,且 LIKE 子串逻辑不复杂,推荐选用 ngrambf_v1 索引,建议参数配置为:ngrambf_v1(2/3, 4096/8192, x, 0)

使用方法

添加索引(ADD INDEX)

-- 添加 minmax 类型索引
ALTER TABLE skiptest on cluster {cluster_name} 
    ADD INDEX
    index_name column_name TYPE minmax GRANULARITY 1;
   
-- 添加 tokenbf_v1 类型索引
ALTER TABLE skiptest on cluster {cluster_name} 
    ADD INDEX
    index_name column_name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 1;
    
-- 添加 ngrambf_v1 类型索引
ALTER TABLE skiptest on cluster {cluster_name} 
    ADD INDEX
    index_name column_name TYPE ngrambf_v1(3, 4096, 3, 0) GRANULARITY 1;
    
-- 添加 set 类型索引
ALTER TABLE skiptest on cluster {cluster_name} 
    ADD INDEX
    index_name column_name TYPE set(0) GRANULARITY 1;
    
-- 添加 bloom_filter 类型索引
ALTER TABLE skiptest on cluster {cluster_name} 
    ADD INDEX
    index_name column_name TYPE bloom_filter(0.1) GRANULARITY 1;
    

删除索引(DROP INDEX)

ALTER TABLE skiptest on cluster {cluster_name} 
    DROP INDEX index_name 

建表时添加索引

-- 在表结构中添加:
INDEX index_name column_name TYPE bloom_filter(0.1) GRANULARITY 1;
 
-- 例如:
CREATE TABLE default.test_skip_index
(
    `id` UInt16,
    `name` String,
    INDEX name_idx name TYPE bloom_filter(0.1) GRANULARITY 1
)
ENGINE = MergeTree
ORDER BY id
SETTINGS index_granularity = 8192;

为历史数据添加索引

ALTER TABLE  skipindex on cluster {cluster_name} MATERIALIZE INDEX index_name;