前文如下:
11.【clickhouse】ClickHouse从入门到放弃-概述
12.【clickhouse】ClickHouse从入门到放弃-环境搭建
13.【clickhouse】ClickHouse从入门到放弃-引擎
14.【clickhouse】ClickHouse从入门到放弃-实战
55.【clickhouse】ClickHouse从入门到放弃-概念场景
56.【clickhouse】ClickHouse从入门到放弃-架构概述
57.【clickhouse】ClickHouse从入门到放弃-update和delete的使用
58.【clickhouse】ClickHouse从入门到放弃-数据类型转换
59.【clickhouse】ClickHouse从入门到放弃-分区表
60.【clickhouse】ClickHouse从入门到放弃-MergeTree的创建方式
61.【clickhouse】ClickHouse从入门到放弃-MergeTree的存储结构
62.【clickhouse】ClickHouse从入门到放弃-数据分区
63.【clickhouse】ClickHouse从入门到放弃-一级索引
64.【clickhouse】ClickHouse从入门到放弃-二级索引
65.【clickhouse】ClickHouse从入门到放弃-数据存储
66.【clickhouse】ClickHouse从入门到放弃-数据标记
1.对于分区、索引、标记和压缩数据的协同总结
分区、索引、标记和压缩数据,就好比是MergeTree给出的一套组合拳,使用恰当时威力无穷。那么,在依次介绍了各自的特点之后,现在将它们聚在一块进行一番总结。接下来,就分别从写入过程、查询过程,以及数据标记与压缩数据块的三种对应关系的角度展开介绍。
1.1 写入过程
数据写入的第一步是生成分区目录,伴随着每一批数据的写入, 都会生成一个新的分区目录。在后续的某一时刻,属于相同分区的目 录会依照规则合并到一起;接着,按照index_granularity索引粒度, 会分别生成primary.idx一级索引(如果声明了二级索引,还会创建二 级索引文件)、每一个列字段的.mrk数据标记和.bin压缩数据文件。 下图所示是一张MergeTree表在写入数据时,它的分区目录、索 引、标记和压缩数据的生成过程。
从分区目录201403_1_34_3能够得知,该分区数据共分34批写 入,期间发生过3次合并。在数据写入的过程中,依据 index_granularity的粒度,依次为每个区间的数据生成索引、标记和 压缩数据块。其中,索引和标记区间是对齐的,而标记与压缩块则根据区间数据大小的不同,会生成多对一、一对一和一对多三种关系
1.2 查询过程
数据查询的本质,可以看作一个不断减小数据范围的过程。在最理想的情况下,MergeTree首先可以依次借助分区索引、一级索引和 二级索引,将数据扫描范围缩至最小。然后再借助数据标记,将需要 解压与计算的数据范围缩至最小。以下图所示为例,它示意了在最优的情况下,经过层层过滤,最终获取最小范围数据的过程。
如果一条查询语句没有指定任何WHERE条件,或是指定了 WHERE条件,但条件没有匹配到任何索引(分区索引、一级索引和二 级索引),那么MergeTree就不能预先减小数据范围。在后续进行数据查询时,它会扫描所有分区目录,以及目录内索引段的最大区间。 虽然不能减少数据范围,但是MergeTree仍然能够借助数据标记,以多线程的形式同时读取多个压缩数据块,以提升性能
1.3 数据标记与压缩数据块的对应关系
由于压缩数据块的划分,与一个间隔(index_granularity)内的数据大小相关,每个压缩数据块的体积都被严格控制在64KB~1MB。而一个间隔(index_granularity)的数据,又只会产生一行数据标记。那么根据一个间隔内数据的实际字节大小,数据标记和压缩数据块之间会产生三种不同的对应关系。接下来使用具体示例做进一步说明,对于示例数据,仍然是测试表hits_v1,其中index_granularity粒度为8192,数据总量为8873898行。
1.多对一
多个数据标记对应一个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size小于64KB时,会出现这种对应关系。以hits_v1测试表的JavaEnable字段为例。JavaEnable数据类型为UInt8,大小为1B,则一个间隔内数据大小为8192B。所以在此种情形下,每8个数据标记会对应同一个压缩数据块,如下图所示:
2.一对一
一个数据标记对应一个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size大于等于64KB且小于等于1MB时,会出现这种对应关系。
以hits_v1测试表的URLHash字段为例。URLHash数据类型为UInt64,大小为8B,则一个间隔内数据大小为65536B,恰好等于64KB。所以在此种情形下,数据标记与压缩数据块是一对一的关系,如下图所示:
3.一对多
一个数据标记对应多个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size直接大于1MB时,会出现这种对应关系。 以hits_v1测试表的URL字段为例。URL数据类型为String,大小根据实际内容而定。如下图所示,编号45的标记对应了2个压缩数据块。