ClickHouse MergeTree表引擎原理
请详细介绍ClickHouse MergeTree表引擎的存储架构,包括数据分区/排序键/主键索引/跳数索引的工作机制。
回答
编译有声
MergeTree是ClickHouse最核心的引擎家族基础。
一、数据存储结构:
-
分区(Partition):
PARTITION BY指定分区键(如toYYYYMM(date))- 每个分区独立存储为目录
partitionId_partNumber_minBlockNum_maxBlockNum_level - 分区可以提高查询裁剪效率
-
数据片段(Data Part):
- 每个分区内数据按主键排序存储为多个Data Part
- 后台自动合并(Merge)较小Part为大Part
二、索引机制:
1. 主键索引(稀疏索引):
ORDER BY (CounterID, Date) -- 排序键=主键
- 不是传统B-Tree,而是每N行(granularity)记录一行索引
index_granularity(默认8192行)控制索引粒度- 索引文件:
primary.idx(主键值)
2. 跳数索引(Skip Index):
INDEX idx_name (CounterID) TYPE minmax GRANULARITY 5
- 类型:minmax/set/bloom_filter/ngrambf_v1/tokenbf_v1
GRANULARITY 5指每5个粒度(5×8192行)构建一个索引- 查询时跳过不包含目标数据的Granule
三、写入流程:
- 数据写入先写入内存缓冲区(默认3s刷新)
- 生成新的Data Part(不可变)
- 后台Merge线程合并小Part
- 分区合并时删除旧Part
四、查询流程:
- 分区裁剪(
WHERE条件过滤分区) - 主键索引定位Granule范围
- 跳数索引进一步过滤Granule
- 读取匹配的列数据(列式读取)
- 合并/聚合执行
优点:
- 写入吞吐极高(LSM-Tree风格)
- 查询延迟低(稀疏索引+数据本地排序)
- 压缩率高(列存+排序后相同值连续)