TOC
自定义分区键
可以对MergeTree
系列的表(包括复制表)进行分区。基于MergeTree
表的物化视图也支持分区。
分区是表中按指定条件划分记录的逻辑组合。可以根据任意条件设置分区,例如按月、按日或按事件类型。每个分区单独存储,以简化对数据的处理。在访问数据时,ClickHouse尽可能使用最小的分区子集。
在创建表时,分区在PARTITION BY expr
子句中指定。分区键可以是表的所有列的任何表达式。
例如,要按月指定分区,可以使用表达式toYYYYMM(date_column)
:
CREATE TABLE visits
(
VisitDate Date,
Hour UInt8,
ClientID UUID
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(VisitDate)
ORDER BY Hour;
分区键也可以是表达式元组(类似于主键)。例如:
ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
PARTITION BY (toMonday(StartDate), EventType)
ORDER BY (CounterID, StartDate, intHash32(UserID));
在本例中,我们根据一周内发生的事件类型设置分区。
向表中插入新数据时,数据存储在按主键排序的单独数据片段中(块)。在插入后的10-15分钟内,同一分区的各个数据片段被合并到整个分区中。
合并只适用于分区表达式具有相同值的数据片段。这意味着您不应该创建粒度过细的分区(超过1000个分区)。否则,由于文件系统中的大量文件和打开的文件描述符,SELECT
查询执行得很差。
使用system.parts
表查看表的数据片段和分区。例如,假设我们有一个按月分区的visit
表。在system.parts
表执行SELECT
查询:
SELECT
partition,
name,
active
FROM system.parts
WHERE table = 'visits'
┌─partition─┬─name───────────┬─active─┐
│ 201901 │ 201901_1_3_1 │ 0 │
│ 201901 │ 201901_1_9_2 │ 1 │
│ 201901 │ 201901_8_8_0 │ 0 │
│ 201901 │ 201901_9_9_0 │ 0 │
│ 201902 │ 201902_4_6_1 │ 1 │
│ 201902 │ 201902_10_10_0 │ 1 │
│ 201902 │ 201902_11_11_0 │ 1 │
└───────────┴────────────────┴────────┘
partition
列包含分区的名称。本例中有两个分区:201901
和201902
。可以使用这个列的值在ALTER … PARTITION
查询中指定分区名。
name
列包含分区数据片段的名称。可以使用此列来指定ALTER ATTACH PART
查询中数据片段的名称。
让我们分解第一个数据片段的名称:201901_1_3_1
:
201901
是分区名称1
是数据块的最小编号。2
是数据库的最大编号。1
是块级别(它形成合并树的深度)。
旧类型表的数据片段名称为:20190117_20190123_2_2_0
(最小日期—最大日期—最小块遍号—最大块遍号—块级别)。
active
列显示数据片段的状态。1
是激活状态;0
是未激活状态。例如,未激活的数据片段是合并到更大的数据片段后剩下的源数据片段。损坏的数据判断也指示为未激活状态。
如示例中所看到的,同一个分区有多个独立的数据片段(例如,201901_1_3_1
和201901_1_9_2
)。这意味着这些部分现在还没有合并。ClickHouse定期合并插入的数据片段,大概是插入后15分钟。此外,可以使用优化查询执行非计划的合并。例如:
OPTIMIZE TABLE visits PARTITION 201902;
┌─partition─┬─name───────────┬─active─┐
│ 201901 │ 201901_1_3_1 │ 0 │
│ 201901 │ 201901_1_9_2 │ 1 │
│ 201901 │ 201901_8_8_0 │ 0 │
│ 201901 │ 201901_9_9_0 │ 0 │
│ 201902 │ 201902_4_6_1 │ 0 │
│ 201902 │ 201902_4_11_2 │ 1 │
│ 201902 │ 201902_10_10_0 │ 0 │
│ 201902 │ 201902_11_11_0 │ 0 │
└───────────┴────────────────┴────────┘
未激活的数据片段将在合并完成大概10分钟后删除。
查看一组数据片段和分区的另一种方法是进入表的目录:/var/lib/clickhouse/data/<database>/<table>/
。例如:
/var/lib/clickhouse/data/default/visits$ ls -l
total 40
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 201901_1_3_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201901_1_9_2
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 15:52 201901_8_8_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 15:52 201901_9_9_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201902_10_10_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201902_11_11_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:19 201902_4_11_2
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 12:09 201902_4_6_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 detached
文件夹'201901_1_1_0 '
、' 201901_1_7_1'
等是数据片段的目录。
每个数据片段都与相应的分区相关,并且只包含特定月份的数据(本例中的表按月分区)。
detached
目录包含使用DETACH
查询从表中卸载的数据片段。损坏的数据片段不是被删除,而同样被移动到这个目录。服务器不使用来自detached
目录的数据片段。可以在随时添加、删除或修改此目录中的数据 —— 直到运行ATTACH
查询时服务器才会知道这一点。
注意,在操作服务器上,您不能手动更改文件系统上的数据片段集或其数据,因为服务器不会感知到这些修改。对于非复制表,可以在服务器停止时执行此操作,但不建议这样做。对于复制的表,在任何情况下都不能更改数据片段集。
ClickHouse 支持对分区执行这些操作:删除分区,从一个表复制到另一个表,或创建备份。了解分区的所有操作,参考操作分区和数据片段
一节。
「如果这篇文章对你有用,请支持一下哦」
如果这篇文章对你有用,请支持一下哦
使用微信扫描二维码完成支付