ClickHouse MergeTree引擎的简单介绍

Stella981
• 阅读 663

1.介绍
Clickhouse 中最强大的表引擎当属 MergeTree (合并树)引擎及该系列(MergeTree)中的其他引擎。MergeTree 允许依据主键和日期创建索引,并进行实时的数据更新操作。MergeTree 是 ClickHouse 里最为先进的表引擎。

请注意不要将 MergeTree 跟 Merge引擎混淆!!!

MergeTree 引擎系列的基本理念如下。当你有巨量数据要插入到表中,你要高效地一批批写入数据片段,并希望这些数据片段在后台按照一定规则合并。相比在插入时不断修改(重写)数据进存储,这种策略会高效很多。

主要特点:

存储的数据按主键排序。
这让你可以创建一个用于快速检索数据的小稀疏索引。
允许使用分区,如果指定了分区键的话。
在相同数据集和相同结果集的情况下 ClickHouse 中某些带分区的操作会比普通操作更快。查询中指定了分区键时 ClickHouse 会自动截取分区数据。这也有效增加了查询性能。
支持数据副本。
ReplicatedMergeTree 系列的表便是用于此。更多信息,请参阅官方文档。
支持数据采样。
需要的话,你可以给表设置一个采样方法。

不使用采样表达式的例子:

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

使用采样表达式的例子:

 MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)*

2. 建表

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]

MergeTree 引擎在创建时接收以下4个参数,

日期字段的名称 (索引字段)
采样表达式 (可选的)
含有主键相关字段的元组
稀疏索引的粒度(见下文)。
以 MergeTree 作为引擎的数据表必须含有一个独立的 Date 字段。比如说, EventDate 字段。这个日期字段必须是 Date 类型的(非 DateTime 类型)。

主键可以是任意表达式构成的元组(通常是列名称的元组),或者是单独一个字段。

抽样表达式(可选的)可以是任意表达式。这个表达式必须在主键中。上面的例子使用了 CounterID 的哈希 intHash32 作为采样表达式,旨在近乎随机地在 CounterID 和 EventDate 内打乱数据条目。换而言之,当我们在查询中使用 SAMPLE 子句时,我们就可以得到一个近乎随机分布的用户列表。

数据表将数据分割为小的索引块作为单位进行处理。 每个索引块之间依照主键排序。每个索引块记录了指定的开始日期和结束日期。在您插入数据时,MergeTree 就会对数据进行排序处理,以保证存储在索引块内的数据有序。 索引块之间的合并过程会在系统后台定期自动执行。MergeTree 引擎会选择几个相邻的索引块进行合并(通常是较小的索引块), 然后对二者合并、排序。

具体而言, 向 MergeTree 表中插入数据时,引擎会首先对新数据执行递增排序而保存索引块;其后,数据索引块之间又会进一步合并,以减少总体索引块数量。 因此,合并过程本身并无过多排序工作。

3.主键和索引在查询中的表现
我们以 (CounterID, Date) 以主键。排序好的索引的图示会是下面这样:

全部数据  :     [-------------------------------------------------------------------------]
CounterID:      [aaaaaaaaaaaaaaaaaabbbbcdeeeeeeeeeeeeefgggggggghhhhhhhhhiiiiiiiiikllllllll]
Date:           [1111111222222233331233211111222222333211111112122222223111112223311122333]
标记:            |      |      |      |      |      |      |      |      |      |      |
                a,1    a,2    a,3    b,3    e,2    e,3    g,1    h,2    i,1    i,3    l,3
标记号:          0      1      2      3      4      5      6      7      8      9      10

如果指定查询如下:

CounterID in (‘a’,’h’),服务器会读取标记号在 [0, 3) 和 [6, 8) 区间中的数据。
CounterID IN (‘a’,’h’) AND Date = 3,服务器会读取标记号在 [1, 3) 和 [7, 8) 区间中的数据。
Date = 3,服务器会读取标记号在 [1, 10] 区间中的数据。
上面例子可以看出使用索引通常会比全表描述要高效。

稀疏索引会引起额外的数据读取。当读取主键单个区间范围的数据时,每个数据块中最多会多读 index_granularity * 2 行额外的数据。大部分情况下,当 index_granularity = 8192 时,ClickHouse的性能并不会降级。

稀疏索引让你能操作有巨量行的表。因为这些索引是常驻内存(RAM)的。

ClickHouse 不要求主键惟一。所以,你可以插入多条具有相同主键的行。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Clickhouse表引擎探究-ReplacingMergeTree
作者:耿宏宇1表引擎简述1.1官方描述MergeTree系列的引擎被设计用于插入极大量的数据到一张表当中。数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合并。相比在插入时不断修改(重写)已存储的数据,这种策略会高效很多。R
Wesley13 Wesley13
3年前
MySQL数据库表设计规范
一、数据库设计1、一般都使用INNODB存储引擎,除非读写比率<1%,才考虑使用MYISAM存储引擎;其他存储引擎请在DBA的建议下使用。2、Storedprocedure(包括存储过程,函数,触发器)对于MYSQL来说还不是很成熟,没有完善的出错记录处理,不建议使用。3、UUID(),USER()这样的
Stella981 Stella981
3年前
Kylin、Druid、ClickHouse 核心技术对比
文章作者:吴建超内容来源:jackywoo.cn导读:Kylin、Druid、ClickHouse是目前主流的OLAP引擎,本文尝试从数据模型和索引结构两个角度,分析这几个引擎的核心技术,并做简单对比。在阅读本文之前希望能对Kylin、Druid、ClickHouse有所理解。01Kylin数据模型
Wesley13 Wesley13
3年前
MySQL表介绍
MySQLInnoDB表介绍一、索引组织表在InnoDB引擎中,表都是根据主键顺序存放的。这种存储方式称为索引组织表,在InnoDB引擎中,每张表都有逐渐。如果没有显示定义主键,则引擎会按照以下方式选择或创建主键。(1)、判断表是否有非空唯一索引,如果有,则该字段为主键。如果有多个非空唯一索引,则选择第一个定义的非空索引字段作为
Wesley13 Wesley13
3年前
MySQL数据库InnoDB存储引擎Log漫游(1)
作者:宋利兵来源:MySQL代码研究(mysqlcode)0、导读本文介绍了InnoDB引擎如何利用UndoLog和RedoLog来保证事务的原子性、持久性原理,以及InnoDB引擎实现UndoLog和RedoLog的基本思路。00–UndoLogUndoLog是为了实现事务的原子性,
Wesley13 Wesley13
3年前
MySQL索引的索引长度问题
MySQL的每个单表中所创建的索引长度是有限制的,且对不同存储引擎下的表有不同的限制。在MyISAM表中,创建组合索引时,创建的索引长度不能超过1000,注意这里索引的长度的计算是根据表字段设定的长度来标量的,例如:createtabletest(idint,name1varchar(300),name2varchar(300),nam
Stella981 Stella981
3年前
ClickHouse和他的朋友们(5)存储引擎技术进化与MergeTree
21世纪的第二个10年,虎哥已经在存储引擎一线奋战近10年,由于强大的兴趣驱动,这么多年来几乎不放过arXiv上与存储相关的每一篇paper。尤其是看到带有draft的paper时,有一种乞丐听到“叮当”响时的愉悦。看paper这玩意就像鉴宝,多数是“赝品”,需要你有“鉴真”的本领,否则今天是张三的算法超越xx,明儿又是王二的硬件提升
京东云开发者 京东云开发者
9个月前
聊聊ClickHouse MergeTree引擎的固定/自适应索引粒度
前言我们在刚开始学习ClickHouse的MergeTree引擎时,就会发现建表语句的末尾总会有SETTINGSindexgranularity8192这句话(其实不写也可以),表示索引粒度为8192。在每个datapart中,索引粒度参数的含义有二:每隔