clickhouse之mergetree详解

来源:互联网 发布:js全局数组变量 编辑:程序博客网 时间:2024/06/10 01:47


MergeTree

英文地址:https://clickhouse.yandex/docs/en/single/index.html#document-table_engines/mergetree

  MergeTree引擎提供了根据日期进行索引和根据主键进行索引,同时提供了实时更新数据的功能(如,在写入数据的时候就可以对已写入的数据进行查询,不会阻塞。),mergetree是clickhouse里最先进的表引擎,不要跟merge引擎混淆。

  这个引擎接受参数形式如下:日期类型的列,可选的示例表达式,一个元祖定义了这个表的主键,索引的间隔尺寸。

不包含示例的mergeTree:

MergeTree(EventDate,(CounterID,EventDate),8192)

包含示例的mergeTree:

MerTree(EventDate,intHash32(UserId),(CounterID,EventDate,intHash32(UserID)),8192)

MergeTree

  一个mergetree类型的表必须有一个包含date类型的列,在上面的例子里,该列是EventDate,这个日期列的类型必须是'Date'(不是‘DateTime’)

  这个主键必须是一个元祖,元素内容通常是表里的列或者一个单一的表达式。

  这个可选的示例可以是任何的表达式,但是这个表达式必须出现在主键里.上面的示例里使用的是一个哈希类型的userID,来伪随机的对主键里的CounterID和EventDate进行打散。换句话说,当使用了这个示例列的时候,可以伪随机的将用户打散成为均匀的子集。

  这个表是由很多个part构成。每一个part按照主键进行了排序,除此之外,每一个part含有一个最小日期和最大日期。当插入数据的时候,会创建一个新的sort part,同时会在后台周期性的进行merge的过程,当merge的时候,很多个part会被选中,通常是最小的一些part,然后merge成为一个大的排好序的part。

  换句话说,整个这个合并排序的过程是在数据插入表的时候进行的。这个merge会导致这个表总是由少量的排序好的part构成,而且这个merge本身并没有做特别多的工作。

  在插入数据的过程中,属于不同的month的数据会被分割成不同的part,这些归属于不同的month的part是永远不会merge到一起的。这么做的目的是provide local data modification(比较容易做备份)。

  这些part在进行合并的时候会有一个大小的阈值,所以不会有太长的merge过程。

  对于每一个part,会生成一个索引文件。这个索引文件存储了表里面每一个索引块里数据的主键的value值,换句话说,这是个对有序数据的小型索引。

  对列来说,在每一个索引块里的数据也写入了标记,从而让数据可以在明确的数值范围内被查找到。

  当读表里的数据时,SELECT查询会被转化为要使用哪些索引。这些索引会被用在判断where条件或者prewhere条件中,来判断是否打中了这些索引区间。

  因此,能够快速查询一个或多个主键范围的值。在下面的示例中,能够快速的查询一个明确的counter,指定范围的日期区间里的一个明确的counter,各种counter的集合等。

示例贴:

  所有的这些示例都是用了日期索引和主键。索引会被用到复杂的表达式计算中,所以读一个组织结构化的表不会比全表扫描慢。

下面的例子中,索引不会被用到。

select count() from table where counterId = 34 or url like '%upyachka%'

  日期索引只能读出包含日期查询条件的语句。然而,一个数据part可能包含很多日期的数据,在一个单一的part里,数据是按照主键进行排序的,可能不会将日期作为第一列。因此,如果查询中只是加了日期范围限定没有加主键的限定会导致遍历更多的数据行。

  对于同时读和更新的表,插入操作不会阻塞读的操作。

  读表的行为自动就是并行化的。

  有额外的merge步骤来支持最优化的查询。

  可以用一个很大的单表来不断的往里添加数据。

  数据负值在mergetree这种表引擎中也是支持的,详细看下面的部分 ““data replication””




原创粉丝点击