说明
按照 order by 字段聚合求和,其他列按照顺序 保留第一行
优点
如果主键的组合方式使得单个键值对应于大量的行,则可以 显著的减少存储空间 并 加快数据查询的速度。
聚合时机
- 合并临时分区时,合并时机见 链接
- 手动合并临时分区
聚合范围
在分区内部聚合求和,不能跨分区聚合求和
应用场景
不关注每一行详细记录,只关注求和结果
语法
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = SummingMergeTree([columns])
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
解释:
SummingMergeTree([columns])括号内指定 求和的列。如果不指定,则所有非维度列且为数字类型的字段,汇总求和order by的列作为维度列,根据该列进行求和partition by:根据该字段进行分区,对分区内进行 上面的 求和操作。不能跨分区求和
其他列按照顺序 保留第一行
案例
建表
create table t_order_smt(
id UInt32 COMMENT '主键',
sn String COMMENT '订单编号',
total Decimal(11,2) COMMENT '总金额',
create_time Datetime COMMENT '创建时间'
)
engine=SummingMergeTree(total)
partition by toYYYYMMDD(create_time)
primary key(id)
order by (id, sn);
解释:
SummingMergeTree(total) ... order by (id, sn);:id、sn相同的记录,对这些记录的total列进行求和partition by toYYYYMMDD(create_time):根据create_time的YYYYMMDD部分进行分区,对分区内进行 上面的 求和操作。不能跨分区求和
其他列按照顺序 保留第一行
第一次插入数据
insert into t_order_smt values
(1,'0001',100,'2022-01-01 11:20:00'),
(2,'0002',200,'2022-01-02 11:30:00'),
(1,'0001',100,'2022-01-01 11:10:00'),
(3,'0003',300,'2022-01-03 10:00:00'),
查询:
select * from t_order_smt
结果如下:
| id | sn | total | create_time | |
|---|---|---|---|---|
| 1 | 0001 | 200.00 | 2022-01-01 11:20:00 | |
| 2 | 0002 | 200.00 | 2022-01-02 11:30:00 | |
| 3 | 0003 | 300.00 | 2022-01-03 10:00:00 |
结论
1,'0001',100,'2022-01-01 11:10:00' 和 (1,'0001',100,'2022-01-01 11:10:00') 记录汇总求和了
最终保留:1|0001|200.00|2022-01-01 11:20:00|记录
原因
- 下面两条数据,
id、sn都相同,而且都是2022-01-01分区的数据,所以汇总求和 - 其他列按照顺序 保留第一行(先插入的数据,排第一)
1,'0001',100,'2022-01-01 11:20:00'
1,'0001',100,'2022-01-01 11:10:00'
第二次插入数据
insert into t_order_rmt values
(1,'0001',100,'2022-01-01 11:20:00'),
(2,'0002',200,'2022-01-02 11:30:00'),
(1,'0001',100,'2022-01-01 11:10:00'),
(3,'0003',300,'2022-01-03 10:00:00'),
查询:
select * from t_order_rmt
结果如下:
id|sn |total |create_time |
--|----|------|-------------------|
1|0001|200.00|2022-01-01 11:20:00|
1|0001|200.00|2022-01-01 11:20:00|
2|0002|200.00|2022-01-02 11:30:00|
2|0002|200.00|2022-01-02 11:30:00|
3|0003|300.00|2022-01-03 10:00:00|
3|0003|300.00|2022-01-03 10:00:00|
结论
没有汇总求和
原因
第二次插入数据,不会自动汇总求和
当 临时分区合并 时,才会汇总求和
再连续执行 4次 插入数据
会触发 临时分区合并,再次查询,结果如下:
id|sn |total |create_time |
--|----|-------|-------------------|
1|0001|1000.00|2022-01-01 11:20:00|
2|0002|1000.00|2022-01-02 11:30:00|
3|0003|1500.00|2022-01-03 10:00:00|
案例-分区间不能汇总求和
重新建表进行测试
删除表
DROP table t_order_smt
创建表
create table t_order_smt(
id UInt32 COMMENT '主键',
sn String COMMENT '订单编号',
total Decimal(11,2) COMMENT '总金额',
create_time Datetime COMMENT '创建时间'
)
engine=SummingMergeTree(total)
partition by toYYYYMMDD(create_time)
primary key(id)
order by (id, sn);
插入数据
插入5次数据
insert into t_order_smt values
(1,'0001',100,'2022-01-01 11:20:00'),
(1,'0001',100,'2022-01-04 11:10:00'),
查询结果如下:
| id | sn | total | create_time | |
|---|---|---|---|---|
| 1 | 0001 | 500.00 | 2022-01-01 11:20:00 | |
| 1 | 0001 | 500.00 | 2022-01-04 11:10:00 |
在合并时,会 汇总求和,但 上面两条数据,在根据 create_time 的 YYYYMMDD 部分,分散在 2022-01-01 和 2022-01-04 2个分区,分区间的数据,不会汇总求和
案例-手动合并临时分区,汇总求和
执行下面语句,立即合并分区,汇总求和
注意:只能分区内合并
optimize table t_order_smt final;
引用:
https://blog.csdn.net/liuyingying0418/article/details/121547844