clickhouse 二级索引

 二级索引

关键字

说明

index name

索引别名

Index expression

索引源字段

Type

minmax, set, bloom filter,map

GRANULARITY

索引粒度 ,如ClickHouse 默认稀疏索引默认是8192 ,我理解 8192*GRANULARITY就是 skip_index.mrk 的block 大小

skpidx{index_name}.idx

which contains the ordered expression values)

skpidx{index_name}.mrk2

which contains the corresponding offsets into the associated data column files.

 表索引设置

  • use_skip_indexes (0 or 1, default 1). 默认过滤所有index
  • force_data_skipping_indexes 强制使用哪个index          

    管理索引

    • ALTER TABLE [db].table_name [ON CLUSTER cluster] ADD INDEX name expression TYPE type GRANULARITY value [FIRST|AFTER name] - Adds index description to tables metadata.
    • ALTER TABLE [db].table_name [ON CLUSTER cluster] DROP INDEX name - Removes index description from tables metadata and deletes index files from disk.
    • ALTER TABLE [db.]table_name [ON CLUSTER cluster] MATERIALIZE INDEX name [IN PARTITION partition_name] - Rebuilds the secondary index name for the specified partition_name. Implemented as a mutation. If IN PARTITION part is omitted then it rebuilds the index for the whole table data.

      支持哪些函数

      Function (operator) / Index

      primary key

      minmax

      ngrambf_v1

      tokenbf_v1

      bloom_filter

      equals (=, ==)

      notEquals(!=, <>)

      like

      notLike

      startsWith

      endsWith

      multiSearchAny

      in

      notIn

      less (<)

      greater (>)

      lessOrEquals (<=)

      greaterOrEquals (>=)

      empty

      notEmpty

      hasToken

      创建跳数索引
      跳数索引可在建表的时候指定,创建语句如下:

      INDEX index_name expr TYPE type(...) GRANULARITY granularity_value
      expr可以是元组,表示创建多个同类的跳数索引。一旦创建了跳数索引,在分区文件中就会出现skpi_idx_[Column].idx 和 skip_idx_[Column].mrk 文件。例如创建名称分别为a和b的minmax、set跳数索引:

      CREATE TABLE table_name
      (
      u64 UInt64,
      i32 Int32,
      s String,
      ...
      INDEX a (u64 * i32, s) TYPE minmax GRANULARITY 3,
      INDEX b (u64 * length(s)) TYPE set(1000) GRANULARITY 4
      ) ENGINE = MergeTree()
      ...
      2. 跳数索引类型
      针对不同的场景,ClickHouse提供了不同类型的跳数索引。每种跳数索引都有一个 GRANULARITY 参数,表示每隔 GRANULARITY 个索引粒度 (index_granularity ) 才会生成一次跳数索引。

      ※ 注意区分 GRANULARITY 和 index_granularity 的不同。

      (1)minmax

      minmax顾名思义就是和分区目录下的 minmax_{column_name}.idx 文件类似,只不过不再是只有一个min/max值,例如上面的minmax跳数索引 a,表示每隔 3 * index_granularity 的区间就会记录一次 u64 * i32 和 s 的最大最小值。当我们通过s查询数据时,可以先基于minmax值判断,从而跳过大多数不需要扫描的索引粒度。

      (2)set(max_rows)

      保存指定表达式的去重值,尤其是对于那些重复性很高的列,例如性别、年龄段等,max_rows 参数表示在一个索引粒度内,最多记录不超过 max_rows 行,即不多于 max_rows 个去重值,max_rows=0 表示不限制。

      (3)ngrambf_v1(n, size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)

      存储一个包含数据块中所有 n元短语(ngram) 的布隆过滤器(Bloom filter)。对String, FixedString 和 Map类型数据有效,可用于优化 EQUALS, LIKE 和 IN表达式。

      ngram表示一句话中的连续n个单词,或者一个字符串中的n个连续字符。感兴趣的同学可阅读《Word2Vector详解》。

      什么是布隆过滤器呢?

      本质上布隆过滤器是一种数据结构,一种比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你:某个数据一定不存在或者可能存在(注意:布隆过滤器是不能判断某条数据一定存在的,存在误报率 (false_positive) )。相比于传统的 List、Set、Map 等数据结构,布隆过滤器更高效、占用空间更少,因为不需要存储原始值,但是缺点是其返回的结果是概率性的,而不是确切的。

      布隆过滤器会定义一个初始值全为0,长度为m的 bit 向量或者说 bit 数组:

       

      然后再定义k个hash函数,使得原始数据可以映射到bit向量中(是不是和redis的bitmap很像,还记得那个怎么记录上亿用户在线状态的问题吗?)。例如,定义3个hash函数,

      对于“python”得到3个hash值:1、5、6,就将bit向量中的1、5、6 bit位置1。

      对于“java”得到3个hash值:2、3、9,就将bit向量中的2、3、9 bit位置1。

      对于“rust”得到3个hash值:7、8、9,就将bit向量中的7、8、9 bit位置1。

      可以发现,对于不同的数据,因为bit向量的长度是有限的,所以可能会出现重复的bit位被置1的情况,即不同数据之间有交集。当我们查数据的时候,例如:“go”,得到的三个hash值为:4、6、7,因为4号bit位是0,所以“go”一定不存在。如果查询数据“shell”得到的hash值是:2、5、9,虽然这个三个bit位都有数据,但是我们也不能确定“shell”一定存在。

      布隆过滤器的好处是可以用较少的空间存储多条复杂数据的存在信息,但是不容易确定bit向量的长度m的值,因为m越小,bit向量就越容易被占满,越容易误报(false_positive越大),起不到过滤作用。hash函数的个数k也不容易确定,因为k越大,bit向量也越容易被占满,k越小,越容易误报,因为更容易撞车。而且,可以发现布隆过滤器是不支持删除的,因为被置1的bit位可能存储了多条数据信息,对于经常变动的数据是不合适的。

      再来介绍一下ngrambf_v1的参数:

      n:ngram短语长度。
      size_of_bloom_filter_in_bytes:布隆过滤器的大小 m,以字节为单位(可以使用较大的值,例如256或512,因为它可以很好地被压缩,并且有更强的表达能力)。
      number_of_hash_functions:布隆过滤器中使用的哈希函数的个数 k 。
      random_seed:布隆过滤器哈希函数的种子。
      (4)tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)

      跟 ngrambf_v1 类似,但是存储的是token而不是ngrams。Token是由非字母数字的符号分割的序列。不再需要ngram size参数,自动通过原始数据中的非字母数字字符切分原始数据。

      (5)bloom_filter([false_positive])

      为指定的列存储布隆过滤器,可用于优化 equals, notEquals, in, notIn, has, hasAny, hasAll 函数,false_positive 表示从过滤器接收到假阳性响应的概率(误报率),取值范围是 (0,1),默认值:0.025。支持数据类型:Int*, UInt*, Float*, Enum, Date, DateTime, String, FixedString, Array, LowCardinality, Nullable, UUID, Map.

      对于Map类型数据,可以使用mapKeys或mapValues函数指定是否为键或值创建索引。如:

      INDEX map_key_index mapKeys(map_column) TYPE bloom_filter GRANULARITY 1
      INDEX map_key_index mapValues(map_column) TYPE bloom_filter GRANULARITY 1

       

posted @ 2022-09-02 16:45  落地的果实  阅读(3291)  评论(0)    收藏  举报