跳转到主要内容

什么是 ClickHouse 中的表 parts?


ClickHouse MergeTree 引擎家族中每个表的数据,都会以一组不可变的 data parts 形式存储在磁盘上。 为了说明这一点,我们使用这张表 (改编自 UK property prices dataset) ,它记录了英国已售房产的成交日期、城镇、街道和价格:
CREATE TABLE uk.uk_price_paid_simple
(
    date Date,
    town LowCardinality(String),
    street LowCardinality(String),
    price UInt32
)
ENGINE = MergeTree
ORDER BY (town, street);
你可以在我们的 ClickHouse SQL Playground 中查询此表 每当一组行被插入到该表中时,就会创建一个 data part。下图对此进行了示意:
当 ClickHouse server 处理上图中示意的包含 4 行的示例插入 (例如通过 INSERT INTO 语句) 时,会执行以下几个步骤: 排序:按表的排序键 (town, street) 对这些行进行排序,并为排序后的行生成一个稀疏主索引 拆分:将排序后的数据拆分为各列。 压缩:对每一列进行压缩 写入磁盘:压缩后的各列会以二进制列文件的形式保存到一个新目录中,该目录对应此次插入生成的 data part。稀疏主索引也会被压缩并存储在同一目录中。 根据表使用的具体引擎,在排序的同时还可能会发生其他转换。 数据 parts 是自包含的,包含了解释其内容所需的全部元数据,无需依赖中心目录。除稀疏主索引外,数据 parts 还包含其他元数据,例如二级数据跳过索引列统计信息、校验和、最小-最大索引 (如果使用了分区) 以及更多

parts 合并

为了控制每个表中的 parts 数量,后台合并任务会定期将较小的 parts 合并成较大的 parts,直到其达到可配置的压缩大小 (通常约为 150 GB) 。合并后的 parts 会被标记为非活动,并在经过一个可配置的时间间隔后删除。随着时间推移,这一过程会形成合并后 parts 的层级结构,这也正是它被称为 MergeTree 表的原因:
为尽量减少初始 parts 的数量以及合并带来的开销,建议数据库客户端批量插入 Tuple,例如一次插入 20,000 行,或者使用asynchronous insert 模式。在这种模式下,ClickHouse 会将写入同一表的多个传入 INSERT 中的行缓存在一起,只有当缓冲区大小超过可配置阈值或发生 timeout 时,才会创建新的 part。

监控表 parts

您可以使用虚拟列 _part查询示例表中当前所有现存活动 parts 的列表:
SELECT _part
FROM uk.uk_price_paid_simple
GROUP BY _part
ORDER BY _part ASC;
   ┌─_part───────┐
1. │ all_0_5_1   │
2. │ all_12_17_1 │
3. │ all_18_23_1 │
4. │ all_6_11_1  │
   └─────────────┘
上述查询会检索磁盘上各个目录的名称,其中每个目录都表示该表的一个活动数据 parts。对想进一步了解的读者来说,这些目录名称的各个组成部分都有特定含义,相关文档见此处 或者,ClickHouse 会在 system.parts 系统表中跟踪所有表的所有数据 parts 信息,而下面的查询会为我们上面的示例表返回当前所有活动数据 parts 的列表、它们的合并层级,以及这些数据 parts 中存储的行数:
SELECT
    name,
    level,
    rows
FROM system.parts
WHERE (database = 'uk') AND (`table` = 'uk_price_paid_simple') AND active
ORDER BY name ASC;
   ┌─name────────┬─level─┬────rows─┐
1. │ all_0_5_1   │     1 │ 6368414 │
2. │ all_12_17_1 │     1 │ 6442494 │
3. │ all_18_23_1 │     1 │ 5977762 │
4. │ all_6_11_1  │     1 │ 6459763 │
   └─────────────┴───────┴─────────┘
每在该分片上额外执行一次合并,合并级别就会增加 1。级别为 0 表示这是一个尚未合并的新分片。
最后修改于 2026年6月10日