You need to enable JavaScript to run this app.
导航
跳数索引
最近更新时间:2024.12.10 17:49:33首次发布时间:2024.12.10 17:49:33

ByteHouse 提供了一种二级索引——跳数索引,可以在建表后异步添加。解决了排序索引只能在建表时设置的缺陷,使调整更加灵活,让用户更加便利的加速查询。

适用场景

ByteHouse MergeTree 家族的表引擎在建表时可以添加排序索引,若查询条件中包含排序索引中的字段,可以预先过滤数据,减少 IO 以加速查询;但排序索引只能在建表时设置,在建表之后无法调整,因此不够灵活。
因此,ByteHouse 提供了一种二级索引——跳数索引。可以在建表后异步添加。其原理与排序索引类似,也是在字段上添加稀疏索引,使得查询时可以裁剪部分数据。跳数索引效果不如排序索引,但仍因其灵活性发或者广泛的作用。

索引类型

几种常用的索引类型,如下:

  • Minmax:这种轻量级索引类型不需要参数。它存储每个块的索引表达式的最小值和最大值(如果表达式是元组,则分别存储元组元素的每个成员的值)。这种类型适用于按值松散排序的列。这种索引类型通常是查询处理中应用成本最低的。这种类型的索引仅适用于标量或元组表达式,不支持应用于返回数组或 Map 的表达式。
  • set:这种轻量级索引类型接受单个参数,即每个块的值集的最大大小(0 允许无限数量的离散值)。这个集合包含块中的所有值(如果值的数量超过最大大小,则为空)。这种索引类型适用于每组颗粒中低基数但总体上高基数的列。这种索引的成本、性能和有效性取决于块内的基数。如果每个块包含大量独特值,则针对大型索引集评估查询条件将非常昂贵,或者由于超过最大大小而索引为空,因此不会应用索引。
  • Bloom Filter(布隆过滤器):布隆过滤器是一种数据结构,它允许在稍有误报的情况下进行高效的集合成员测试。由于布隆过滤器可以更有效地处理测试大量离散值,它们适用于产生更多测试值的条件表达式。特别是,布隆过滤器索引可以应用于数组和 Map。基于布隆过滤器的数据跳过索引类型有三种:
    • 基本的 bloom_filter,它接受一个允许的“误报”率的单个可选参数,介于0和1之间(如果未指定,则使用.025)。
    • tokenbf_v1。此索引仅适用于String、FixedString和Map数据类型。输入表达式被分割为由非字母数字字符分隔的字符序列。例如,列值 "This is a candidate for a 'full text' search" 将包含词条 "This is a candidate for full text search"。它适用于LIKE、EQUALS、IN、hasToken()及类似搜索中用于在较长字符串中搜索单词和其他值。它接受三个参数:
      • 过滤器的大小,以字节为单位(更大的过滤器误报较少,但存储成本增加)
      • 应用的哈希函数数量(同样,更多的哈希过滤器减少误报)
      • 布隆过滤器哈希函数的种子。
    • ngrambf_v1。此索引在布隆过滤器设置之前接受一个额外的参数,即要索引的ngram的大小。ngram是任何字符的长度为n的字符字符串,因此字符串 "A short string with an ngram size of 4" 将被索引为: 'A sh'、' sho'、'shor'、'hort'、'ort '、'rt s'、't st'、' str'、'stri'、'trin'、'ring'。这个索引也可以用于文本搜索,特别是对于没有单词间隔的语言,如中文。

使用方法

配置

使用时需要在配置(users.xml)中添加:

set allow_experimental_data_skipping_indices = 1;

索引操作

添加索引 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
    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;

注意事项
  1. 跳数索引依赖于对数据分布的认知,更适用于高基数列,等值 / 小范围查询;对于基数较低 / 大范围命中的场景通常是不适合的。
  2. 索引类型优选顺序,可参考:
    1. 数值类型通常选用 minmax 索引。
    2. string 类型选用 可以统一选用 bloom_filter(0.1),方便快捷。
    3. 如果一定要在 like 上使用,且 like 子串不复杂,推荐 ngrambf_v1(2/3, 4096/8192, x, 0)