zoukankan      html  css  js  c++  java
  • ClickHouse MergeTree引擎的简单介绍

    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 不要求主键惟一。所以,你可以插入多条具有相同主键的行。

  • 相关阅读:
    PHP多进程(四) 内部多进程
    STL map and multimap
    Understanding Function Objects
    Working with Bit Flags Using STL
    STL Algorithms
    STL set and multiset
    Understanding Smart Pointers
    More Effective C++ 学习笔记(1)
    Adaptive Container: stack and queue
    第一个 Python 程序
  • 原文地址:https://www.cnblogs.com/eflypro/p/13878542.html
Copyright © 2011-2022 走看看