clickhouse partition 设定分区

发布时间 2023-12-15 16:26:48作者: 秋来叶黄

clichouse会对数据分区存放,目的是为了在搜索时提高效率。

除此之外,还可以用来维护磁盘使用空间。clickhouse并不适合从数据库按照条件查询删除数据,如果数据太多不定期清除,会把磁盘占满。

clickhouse提供了ttl,用作设定数据库表的数据的生命周期,如果到了时间,就会删除数据。

如果要删除数据,最好是根据partition进行删除。

以官方示例为例

CREATE TABLE visits
(
    VisitDate Date,
    Hour UInt8,
    ClientID UUID
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(VisitDate)
ORDER BY Hour;

创建一个表,定义partition根据toYYYYMM(VisitDate)分区,VisitDateshi是时间toYYYYMM(VisitDate)是把时间转成年月,所以这个表就会根据月分片。

同样也可以根据自己需要设定分片

ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
PARTITION BY (toMonday(StartDate), EventType)
ORDER BY (CounterID, StartDate, intHash32(UserID));

注意,设定partition的规则颗粒度不要太细,如果分片太多(超过1000),会影响性能。

可以从系统表获取分片信息

SELECT * FROM system.parts
┌─partition─┬─name───────────────────┬─active─┐
|20231215   |20231215_1_8510_14      |1       |
|20231215   |20231215_8511_14172_11  |1       |
|20231215   |20231215_14173_15784_10 |1       |
|20231215   |20231215_15785_17648_10 |1       |
|20231215   |20231215_17649_17838_8  |0       | 
└───────────┴────────────────────────┴────────┘

partition是分片id,相同的id的数据会放到一起,如果有多个,说明还处于当前分片周期,还没有合并,比如设定的是1天,按道理,昨天的数据会只有一条,而今天的会有多条,因为合并数据也会有一套逻辑,并不会立马合并到一起。

20231215_1_8510_14

  • 20231215是分片的id
  • 1是当前数据片的第一个数据块的编号
  • 8510是当前数据片的最后一个数据块编号,所以下一个数据分片就是从8511开始
  • 14 the mutation version (if a part mutated) 大体应该是该数据片变化的版本号,因为数据片一直在更新合并

这个分片还有一些其他作用,比如数据库表中有表示省份的字段,可以用该字段进行分片,把每个省的数据放一起,或者可以对数据进行哈希计算,把数据平均的放到不同的分片中。

https://clickhouse.com/docs/zh/engines/table-engines/mergetree-family/custom-partitioning-key
https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/custom-partitioning-key