首页/数据/NoSQL 速查/MergeTree 引擎参数与数据组织
ClickHouse56 条

MergeTree 引擎参数与数据组织

MergeTree 按 ORDER BY 排序存储、按 PARTITION BY 分区,插入形成独立 part,后台按规则合并;index_granularity 决定稀疏索引的粒度。

NoSQL 速查数据更新于 2026-10-13

MergeTree 是什么

MergeTree 是 ClickHouse 最核心的表引擎家族:数据按 ORDER BY 排序存储、按 PARTITION BY 分区,每次插入生成一个独立的 part,后台线程再按规则合并成更大的 part。查询对 part 并行扫描,并用稀疏主索引(粒度由 index_granularity 决定,默认 8192)裁剪数据块。它决定了数据怎么落盘、查询怎么快速找到目标范围。

基本信息

必填项ORDER BY:定义排序键与稀疏主索引依据
可选子句PARTITION BY、PRIMARY KEY(默认取 ORDER BY)、SAMPLE BY、TTL、SETTINGS
数据单位每个 INSERT 生成一个 part,后台 merge 成更大的 part
稀疏索引index_granularity 默认 8192,决定索引粒度
查询方式对 part 并行扫描,按分区与排序键裁剪
适用版本ClickHouse 全系列,语法多年稳定

典型使用场景

  • 日志与事件明细表,按时间分区、按维度排序
  • 监控指标表,按设备与时间排序支持范围查询
  • 需要按分区整块删除或移动的数据保留场景
  • 宽表明细存储,用物化视图做上游预聚合
  • 需要去重语义时用 ReplacingMergeTree 变体
  • 大规模写入后靠后台合并收敛 part 数量

示例

示例
CREATE TABLE metrics
(
    ts DateTime,
    metric LowCardinality(String),
    value Float64
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(ts)                 -- 按月分区,便于整块清理
ORDER BY (metric, ts)                     -- 排序键:先等值维度,再时间
SETTINGS index_granularity = 8192;

SELECT count() FROM system.parts WHERE table = 'metrics' AND active;   -- 查看活跃 part

常用变体引擎

引擎附加能力适用场景
MergeTree无附加去重语义通用明细存储
ReplacingMergeTree按排序键保留最新记录需要最终去重的表
SummingMergeTree合并时对数值列求和预聚合计数与汇总
AggregatingMergeTree合并时按聚合函数状态合并物化视图目标表
CollapsingMergeTree按标记列折叠或取消行需要撤销语义的数据
PARTITION BY 主要用于数据生命周期管理(按月或按天分区后整块删除、移动);排序键才决定查询能裁剪多少数据,两者职责不同。
每个 INSERT 都会产生一个新 part,part 数量越多查询需要合并扫描的块越多;批量导入后系统.parts 里的 part 数会随后台合并逐步下降。
小批量高频插入会积压大量小 part,后台合并跟不上时查询明显变慢;导入侧应攒批,构建宽表时也不要用「一条一条写」的方式。

易错点

  • 小批量高频 INSERT 会产生大量小 part,后台合并跟不上时查询变慢,导入要尽量攒批
  • ORDER BY 的列顺序即索引前缀顺序,把低基数或不参与过滤的列放前面会让裁剪失效
  • 建表时漏写 ORDER BY 会直接报错,MergeTree 家族强制要求排序键
  • 把高基数标识(如请求 ID)直接放进分区键会造出成千上万个分区,元数据与合并开销都会飙升
  • 把 ORDER BY 与 PARTITION BY 混为一谈:分区只影响整块管理,排序键才影响查询性能

数据来源与参考

  • ClickHouse Docs: MergeTree engine
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌