|NO.Z.00008|——————————|BigDataEnd|——|Hadoop&OLAP_ClickHouse.V05|——|ClickHouse.v05|表引擎|MergeTree|索引|

一、索引:一级索引
### --- 一级索引

~~~     文件:primary.idx
~~~     MergeTree的主键使用Primary Key定义,主键定义之后,
~~~     MergeTree会根据index_granularity间隔(默认8192)为数据生成一级索引并保存至primary.idx文件中。
~~~     这种方式是稀疏索引
~~~     简化形式:通过order by指代主键
~~~     # 稀疏索引

~~~     primary.idx文件的一级索引采用稀疏索引。
~~~     稠密索引:每一行索引标记对应一行具体的数据记录
~~~     稀疏索引:每一行索引标记对应一段数据记录(默认索引粒度为8192)
### --- 密集索引和稀疏索引的区别

~~~     稀疏索引占用空间小,所以primary.idx内的索引数据常驻内存,取用速度快!
~~~     # 索引粒度
~~~     index_granularity参数,表示索引粒度。新版本中clickhouse提供了自适应索引粒度。

~~~     # 索引粒度在MergeTree引擎中很重要。
~~~     索引数据的生成规则
~~~     借助hits_v1表中的真实数据观察:

~~~     # primary.idx文件
~~~     由于稀疏索引,所以MergeTree要间隔index_granularity行数据才会生成一个索引记录,
~~~     其索引值会根据声明的主键字段获取。
~~~     # 索引的查询过程
~~~     索引是如何工作的?对primary.idx文件的查询过程

~~~     # MarkRange:一小段数据区间
~~~     按照index_granularity的间隔粒度,将一段完整的数据划分成多个小的数据段,小的数据段就是MarkRange,MarkRange与索引编号对应。
### --- 案例:

~~~     共200行数据
~~~     index_granularity大小为5
~~~     主键ID为Int,取值从0开始
~~~     根据索引生成规则,primary.idx文件内容为:05101520253035404550...200
~~~     共200行数据 / 5 = 40个MarkRange
~~~     索引查询 where id = 3
~~~     第一步:形成区间格式: [3,3]
~~~     第二步:进行交集 [3,3]∩[0,199]
~~~     以MarkRange的步长大于8分块,进行剪枝
~~~     第三步:合并
### --- MarkRange:(start0,end 20)

~~~     在ClickHouse中,MergeTree引擎表的索引列在建表时使用ORDER BY语法来指定。
~~~     而在官方文档中,用了下面一幅图来说明。
~~~     这张图示出了以CounterID、Date两列为索引列的情况,即先以CounterID为主要关键字排序,
~~~     再以Date为次要关键字排序,最后用两列的组合作为索引键。
~~~     marks与mark numbers就是索引标记,
~~~     且marks之间的间隔就由建表时的索引粒度参数index_granularity来指定,默认值为8192
~~~     # ClickHouse MergeTree引擎表中,每个part的数据大致以下面的结构存储。

~~~     . ├── business_area_id.bin ├── business_area_id.mrk2 ├── coupon_money.bin ├── coupon_money.mrk2├── groupon_id.bin ├── groupon_id.mrk2 ├── is_new_order.bin ├── is_new_order.mrk2 … ├── primary.idx… 其中,
~~~     bin文件存储的是每一列的原始数据(可能被压缩存储),
~~~     mrk2文件存储的是图中的mark numbers与bin文件中数据位置的映射关系。
~~~     另外,还有一个primary.idx文件存储被索引列的具体数据。
~~~     另外,每个part的数据都存储在单独的目录中,目录名形如20200708_92_121_7,
~~~     即包含了分区键、起始mark number和结束marknumber,方便定位。
~~~     # 在ClickHouse之父Alexey Milovidov分享的PPT中,有更加详细的图示。

~~~     这样,每一列都通过ORDER BY列进行了索引。
~~~     查询时,先查找到数据所在的parts,再通过mrk2文件确定bin文件中数据的范围即可。
~~~     不过,ClickHouse的稀疏索引与Kafka的稀疏索引不同,可以由用户自由组合多列,
~~~     因此也要格外注意不要加入太多索引列,防止索引数据过于稀疏,增大存储和查找成本。
~~~     另外,基数太小(即区分度太低)的列不适合做索引列,
~~~     因为很可能横跨多个mark的值仍然相同,没有索引的意义了。
二、跳数索引
### --- granularity和index_granularity的关系

~~~     index_granularity定义了数据的粒度 granularity定义了聚合信息汇总的粒度 换言之,
~~~     granularity定义了一行跳数索引能够跳过多少个index_granularity区间的数据
~~~     # 索引的可用类型

~~~     minmax 存储指定表达式的极值(如果表达式是 tuple ,则存储 tuple 中每个元素的极值),
~~~     这些信息用于跳过数据块,类似主键。
~~~     set(max_rows) 存储指定表达式的惟一值(不超过 max_rows 个,max_rows=0 
~~~     则表示『无限制』)。这些信息可用于检查 WHERE 表达式是否满足某个数据块。
~~~     ngrambf_v1(n, size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed) 
~~~     存储包含数据块中所有 n 元短语的 布隆过滤器 。只可用在字符串上。 
~~~     可用于优化 equals , like 和 in 表达式的性能。 
~~~     n – 短语长度。 size_of_bloom_filter_in_bytes – 布隆过滤器大小,
~~~     单位字节。(因为压缩得好,可以指定比较大的值,如256512)。 
~~~     number_of_hash_functions – 布隆过滤器中使用的 hash 函数的个数。 
~~~     random_seed –hash 函数的随机种子。
~~~     tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed) 
~~~     跟 ngrambf_v1 类似,不同于 ngrams 存储字符串指定长度的所有片段。
~~~     它只存储被非字母数据字符分割的片段。
### --- granularity和index_granularity的关系示例

hadoop01 :) INDEX sample_index (u64 * length(s)) TYPE minmax GRANULARITY 4
hadoop01 :) INDEX sample_index2 (u64 * length(str), i32 + f64 * 100, date, str) TYPE set(100) GRANULARITY 4
hadoop01 :) INDEX sample_index3 (lower(str), str) TYPE ngrambf_v1(3, 256, 2, 0) GRANULARITY 4

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(42)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示