首页IT科技clickhouse join 内存不足(ClickHouse引擎之ReplacingMergeTree)

clickhouse join 内存不足(ClickHouse引擎之ReplacingMergeTree)

时间2025-04-30 13:35:13分类IT科技浏览4569
导读:为什么会有ReplacingMergeTree ReplacingMergeTree作用?...

为什么会有ReplacingMergeTree

ReplacingMergeTree作用?

ClickHouse中最常用也是最基础的表引擎为MergeTree            ,在它的功能基础上添加特定功能就构成了MergeTree系列引擎            。MergeTree支持主键                 ,但主键主要用来缩小查询范围      ,且不具备唯一性约束         ,可以正常写入相同主键的数据                  。但在一些情况下                 ,可能需要表中没有主键重复的数据     。ReplacingMergeTree就是在MergeTree的基础上加入了去重的功能         ,但它仅会在合并分区时      ,去删除重复的数据                 ,写入相同数据时并不会引发异常         。

使用方式

创建一张ReplacingMergeTree的表和创建MergeTree类似            ,修改引擎即可                  。ReplacingMergeTree引擎创建规范为:ENGINE = ReplacingMergeTree([ver])   ,其中ver为选填参数                 ,它需要指定一个UInt8/UInt16            、Date或DateTime类型的字段               ,它决定了数据去重时所用的算法,如果没有设置该参数              ,合并时保留分组内的最后一条数据;如果指定了该参数                 ,则保留ver字段取值最大的那一行        。

不指定ver参数

-- 创建未指定ver参数ReplacintMergeTree引擎的表 CREATE TABLE replac_merge_test ( `id` String, `code` String, `create_time` DateTime ) ENGINE = ReplacingMergeTree() PARTITION BY toYYYYMM(create_time) PRIMARY KEY id ORDER BY (id, code)

ReplacingMergeTree会根据ORDER BY所声明的表达式去重

-- 在上述表中插入数据 insert into replac_merge_test values (A000, code1, now()),(A000, code1, 2020-07-28 21:30:00), (A001, code1, now()), (A001, code2, 2020-07-28 21:30:00), (A0002, code2, now()); -- 查询当前数据 select * from replac_merge_test; ┌─id────┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-07-28 21:23:48 │ │ A000 │ code1 │ 2020-07-28 21:30:00 │ │ A0002 │ code2 │ 2020-07-28 21:23:48 │ │ A001 │ code1 │ 2020-07-28 21:23:48 │ │ A001 │ code2 │ 2020-07-28 21:30:00 │ └───────┴───────┴─────────────────────┘ -- 强制进行分区合并 optimize table replac_merge_test FINAL; -- 再次查询数据 select * from replac_merge_test; ┌─id────┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-07-28 21:30:00 │ │ A0002 │ code2 │ 2020-07-28 21:23:48 │ │ A001 │ code1 │ 2020-07-28 21:23:48 │ │ A001 │ code2 │ 2020-07-28 21:30:00 │ └───────┴───────┴─────────────────────┘

通过上面示例可以看到   ,id                 、code相同的字段’A000’,code1’被去重剩余一条数据            ,由于创建表时没有设置ver参数                 ,故保留分组内的最后一条数据(create_time字段)

-- 再次使用insert插入一条数据 insert into replac_merge_test values (A001, code1, 2020-07-28 21:30:00); -- 查询表中数据 select * from replac_merge_test; ┌─id────┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-07-28 21:30:00 │ │ A0002 │ code2 │ 2020-07-28 21:23:48 │ │ A001 │ code1 │ 2020-07-28 21:23:48 │ │ A001 │ code2 │ 2020-07-28 21:30:00 │ └───────┴───────┴─────────────────────┘ ┌─id───┬─code──┬─────────create_time─┐ │ A001 │ code1 │ 2020-07-28 21:30:00 │ └──────┴───────┴─────────────────────┘

可以看到      ,再次插入重复数据时         ,查询仍然会存在重复      。在ClickHouse中                 ,默认一条insert插入的数据为同一个数据分区         ,不同insert插入的数据为不同的分区      ,所以ReplacingMergeTree是以分区为单位进行去重的                 ,也就是说只有在相同的数据分区内            ,重复数据才可以被删除掉                  。只有数据合并完成后   ,才可以使用引擎特性进行去重           。

指定ver参数

-- 创建指定ver参数ReplacingMergeTree引擎的表 CREATE TABLE replac_merge_ver_test ( `id` String, `code` String, `create_time` DateTime ) ENGINE = ReplacingMergeTree(create_time) PARTITION BY toYYYYMM(create_time) PRIMARY KEY id ORDER BY (id, code) -- 插入测试数据 insert into replac_merge_ver_test values(A000, code1, 2020-07-10 21:35:30),(A000, code1, 2020-07-15 21:35:30),(A000, code1, 2020-07-05 21:35:30),(A000, code1, 2020-06-05 21:35:30); -- 查询数据 select * from replac_merge_ver_test; ┌─id───┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-06-05 21:35:30 │ └──────┴───────┴─────────────────────┘ ┌─id───┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-07-10 21:35:30 │ │ A000 │ code1 │ 2020-07-15 21:35:30 │ │ A000 │ code1 │ 2020-07-05 21:35:30 │ └──────┴───────┴─────────────────────┘ -- 强制进行分区合并 optimize table replac_merge_ver_test FINAL; -- 查询数据 select * from replac_merge_ver_test; ┌─id───┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-07-15 21:35:30 │ └──────┴───────┴─────────────────────┘ ┌─id───┬─code──┬─────────create_time─┐ │ A000 │ code1 │ 2020-06-05 21:35:30 │ └──────┴───────┴─────────────────────┘

由于上述创建表是以create_time的年月来进行分区的                 ,可以看出不同的数据分区               ,ReplacingMergeTree并不会进行去重,并且在相同数据分区内              ,指定ver参数后                 ,会保留同一组数据内create_time时间最大的那一行数据   。

总结

使用ORDER BY排序键   ,作为判断数据是否重复的唯一键

只有在合并分区时            ,才会触发数据的去重逻辑

删除重复数据                 ,是以数据分区为单位                  。同一个数据分区的重复数据才会被删除      ,不同数据分区的重复数据仍会保留

在进行数据去重时         ,由于已经基于ORDER BY排序                 ,所以可以找到相邻的重复数据

数据去重策略为:

若指定了ver参数         ,则会保留重复数据中      ,ver字段最大的那一行

若未指定ver参数                 ,则会保留重复数据中最末的那一行数据

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
电脑qq怎么查看我看过谁的空间(教你2个技巧轻松查看PC版QQ对方有没有删除你) 提升网站收录效率的关键步骤是(提升网站收录效率的关键步骤)