system.parts 是什么
system.parts 是 ClickHouse 的系统表,记录每张表在磁盘上每个数据 part 所属分区、行数、压缩前后体积与标记数量。ClickHouse 写入时会先生成小 part,再由后台合并任务逐步合并成更大的 part,因此这张表是判断「写入是否过碎、合并是否跟得上、磁盘被哪张表占了」的主要依据。
基本信息
| 关键列 | database、table、partition、name、active、rows、bytes_on_disk、data_compressed_bytes、marks |
|---|---|
| active 含义 | 值为 1 表示当前生效的 part;合并中的旧 part 会短暂以非 active 状态保留 |
| 统计口径 | 统计磁盘占用必须先过滤 active,否则会把待清理 part 重复计入 |
| 刷新时机 | 系统表读取内存中的 part 元数据,写入后即可见 |
| 配套表 | system.merges 看正在进行的合并,system.parts_columns 看列级信息 |
典型使用场景
- 排查小 part 过多:单表活动 part 数上千说明写入批次太碎,合并跟不上
- 核对磁盘占用:按表聚合 bytes_on_disk 找出真正的占用大户
- 确认分区设计:按 partition 分组看每天或每月的实际数据量
- 评估压缩效果:对比 data_compressed_bytes 与 bytes_on_disk 判断辅助文件占比
- 定位合并瓶颈:结合 system.merges 判断是合并积压还是磁盘写满
常用查询
常用查询
-- 各表活动 part 数量与磁盘占用,占用最大的排在前面
SELECT database, table, count() AS parts, sum(rows) AS total_rows,
formatReadableSize(sum(bytes_on_disk)) AS disk_size
FROM system.parts
WHERE active
GROUP BY database, table
ORDER BY sum(bytes_on_disk) DESC
LIMIT 10;
-- 单表按分区看数据量与 part 数,确认分区粒度是否合理
SELECT partition, count() AS parts, sum(rows) AS rows
FROM system.parts
WHERE active AND database = 'default' AND table = 'events'
GROUP BY partition ORDER BY partition;
-- 当前正在执行的合并任务
SELECT database, table, elapsed, progress, num_parts FROM system.merges;输出逐列读法
| 列 | 含义 | 正常 / 异常 |
|---|---|---|
| active | 该 part 是否当前生效 | 不过滤会把已合并 part 重复计入 |
| partition | 分区表达式的结果值 | 同表分区数过多说明分区粒度太细 |
| rows | 该 part 内的行数 | 普遍偏小说明导入批次太碎 |
| bytes_on_disk | part 在磁盘上的实际体积 | 含索引与标记文件,是真实占用口径 |
| data_compressed_bytes | 压缩后的数据体积 | 远小于磁盘体积说明辅助文件占比高 |
| marks | 标记条目数,与数据粒度数量相关 | 异常偏大意味着粒度太细、元数据开销上升 |
活动 part 数持续偏高说明写入过碎、后台合并跟不上,正确做法是把导入攒批(例如按秒或按万行成批写入)而不是反复执行 OPTIMIZE;手工 OPTIMIZE 会重写整个分区,对写入吞吐的影响通常比等后台合并更大。