Skip to main content

什么是 ClickHouse 中的表 parts?


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

parts 合并

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

监控表 parts

您可以使用虚拟列 _part查询示例表中当前所有现存活动 parts 的列表:
上述查询会检索磁盘上各个目录的名称,其中每个目录都表示该表的一个活动数据分区片段。对想进一步了解的读者来说,这些目录名称的各个组成部分都有特定含义,相关文档见此处 或者,ClickHouse 会在 system.parts 系统表中跟踪所有表的所有数据分区片段信息,而下面的查询会为我们上面的示例表返回当前所有活动数据分区片段的列表、它们的合并层级,以及这些数据分区片段中存储的行数:
每在该分片上额外执行一次合并,合并级别就会增加 1。级别为 0 表示这是一个尚未合并的新分片。
最后修改于 2026年7月3日