前言
插件及服务器版本
服务器:ubuntu 16.04
ClickHouse:20.12.5
SummingMergeTree表引擎主要用于只关心聚合后的数据,而不关心明细数据的场景,它能够在合并分区的时候按照预先定义的条件聚合汇总数据,将同一分组下的多行数据汇总到一行,这样即减少了数据行,又降低了后续汇总查询的开销,该引擎优势:
SummingMergeTree表引擎依据ORDER BY指定的字段进行聚合,PRIMARY KEY指定主键,但是ORDER BY可以指代主键,一般只声明ORDER BY即可。
如果需要同时定义ORDER BY与PRIMARY KEY,这种情况多用于聚合条件有变动时使用,例如:
假设有一张表有col1,col2,col3,col4四个字段,我们需要按照col1,col2进行聚合,则ORDERY BY声明如下:
ORDER BY (col1,col2)
这样声明的话,该表的主键即为col1,col2,但是该表主要的过滤字段为col1,应该只使用col1作为主键,所以我们可以用一种更加优雅的定义形式:
ORDER BY (col1,col2)
PRIMARY KEY col1
备注: 这里需要注意,PRIMARY KEY必须为ORDER BY的前缀,这种约定保障了即使在ORDER BY与PRIMARY KEY不同的时候,主键仍然是排序键的前缀,不会出现索引与数据顺序混乱的问题。
如果需要修改聚合字段组合,将先前的聚合依据增加字段或减少字段,可以直接对表进行ALTER操作,如下:
ALTER TABLE test_summing MODIFY ORDER BY (col1,col2,col3);
备注: 在修改ORDER BY时,会有一些限制,只能在现有的基础上减少字段,如果是新增排序字段,则只能通过ALTER ADD COLUMN新增字段,但是ALTER是一种元数据的操作,修改成本低
EGINE = SummingMergeTree((col1,col2,...))
col1,col2声明sum汇总的字段,如果不指定,默认聚合所有非主键外的数值字段。
示例如下:
create table test_summing (
shop_code String,
product_code String,
in_count Int,
out_count Int,
write_date DateTime
) ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(write_date)
ORDER BY (shop_code,product_code)
PRIMARY KEY shop_code;
插入测试数据:
insert into test_summing values ('1','短袖',100,100,'2020-12-17 21:18:00');
insert into test_summing values ('1','短袖',100,200,'2020-12-17 21:19:00');
insert into test_summing values ('1','短袖',100,100,'2020-12-17 21:20:00');
insert into test_summing values ('2','外套',100,100,'2020-12-17 21:18:00');
insert into test_summing values ('2','外套',100,100,'2020-12-17 21:19:00');
这里可以看到,依照shop_code,produce_code,对in_count,out_count进行了自动聚合,这里跟ReplacingMergeTree引擎一样,聚合只会发生在同分区内,不同分区的数据不会发生聚合,如下:
SummingMergeTree也支持嵌套类型的字段,在使用嵌套类型的字段时,需要被sum汇总的字段名必须以Map后缀结尾,嵌套Map类型聚合如下:
create table test_summing_map1 (
shop_code String,
product_code String,
in_count Int,
out_count Int,
nestMap Nested(
id Int,
key Int,
val Int
),
write_date DateTime
) ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(write_date)
ORDER BY (shop_code,product_code)
PRIMARY KEY shop_code;
insert into test_summing_map1 values ('1','短袖',100,100,[1],[2],[3],'2020-12-17 21:18:00');
insert into test_summing_map1 values ('1','短袖',100,200,[2],[2],[4],'2020-12-17 21:19:00');
触发聚合后,结果如下:
在使用嵌套类型时,也支持使用复合Key作为数据聚合的条件,在嵌套类型的字段内,以Key 、Id、Type为后缀结尾的字段,都将和ORDER BEY指定的聚合字段组合成一个复合的key,进行聚合,例如:
nestMap Nested(
id Int,
Key Int,//首字母大写的Key
val Int
)
示例:
create table test_summing_map2 (
shop_code String,
product_code String,
in_count Int,
out_count Int,
nestMap Nested(
id Int,
Key Int,
val Int
),
write_date DateTime
) ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(write_date)
ORDER BY (shop_code,product_code)
PRIMARY KEY shop_code;
insert into test_summing_map2 values ('1','短袖',100,100,[1],[2],[3],'2020-12-17 21:18:00');
insert into test_summing_map2 values ('1','短袖',100,100,[1],[2],[3],'2020-12-17 21:18:00');
insert into test_summing_map2 values ('1','短袖',100,200,[2],[3],[4],'2020-12-17 21:19:00');
查看聚合结果:
这里可以看到:新的聚合结果,根据嵌套字段的Key和ORDER BY的字段进行了聚合,nestMap.val进行了sum
SummingMergeTree聚合非数值类型数据时,或者是处理非聚合字段时,只会取相同key分区的第一条记录,例如:
create table test_summing_map (
shop_code String,
product_code String,
in_count Int,
out_count Int,
nestMap Nested(
id String,
Key String,
val String
),
write_date DateTime
) ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(write_date)
ORDER BY (shop_code,product_code)
PRIMARY KEY shop_code;
插入测试数据:
insert into test_summing_map values ('1','短袖',100,100,['1'],['Tracy'],['ZHENGZHOU'],'2020-12-17 21:18:00');
insert into test_summing_map values ('1','短袖',100,200,['2'],['Monica'],['QITAIHE'],'2020-12-17 21:19:00');
insert into test_summing_map values ('1','短袖',100,100,['3'],['Nesta'],['SHANGHAI'],'2020-12-17 21:20:00');
执行optimize强制触发聚合:
optimize table test_summing_map final;
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://gaokaiyang.blog.csdn.net/article/details/112118734
内容来源于网络,如有侵权,请联系作者删除!