真实用EXPLAIN indexes=1对比同一张20分区表在分区键过滤和普通列过滤下的Parts裁剪比例,看清楚分区裁剪到底是怎么生效的。
代码CREATE TABLE demo.prune (d Date, k UInt64, v String) ENGINE=MergeTree PARTITION BY toYYYYMM(d) ORDER BY k; INSERT INTO demo.prune SELECT toDate('2026-01-01')+number, number, toString(number) FROM numbers(600); -- 跨度约20个月 EXPLAIN indexes=1 SELECT count() FROM demo.prune WHERE toYYYYMM(d)=202601; EXPLAIN indexes=1 SELECT count() FROM demo.prune WHERE v='300';
EXPLAIN indexes=1 SELECT count() FROM demo.prune WHERE toYYYYMM(d)=202601;
→ ReadFromMergeTree (demo.prune)
Indexes:
Min-Max
Parts: 1/20 ← 真实20个part只留1个
Granules: 1/1
Partition
Keys: toYYYYMM(d)
Condition: and((toYYYYMM(d) in (-Inf,202602]), (toYYYYMM(d) in [202601,+Inf)))
Parts: 1/1 ← 真实分区级别的裁剪:1个分区
Granules: 1/1过滤条件toYYYYMM(d)=202601直接命中了分区键的表达式,ClickHouse真实在查询规划阶段就能算出"202601"对应哪一个分区目录,直接跳过其余19个分区,连打开它们的文件都不需要——这就是分区裁剪(Partition Pruning)真实生效的样子:Parts: 1/20意味着20个part里真实只有1个进入了后续的扫描流程。
EXPLAIN indexes=1 SELECT count() FROM demo.prune WHERE v='300';
→ ReadFromMergeTree (demo.prune)
Read type: Default
Parts: 20 | Granules: 20
Indexes:
Min-Max
Condition: true
Parts: 20/20 ← 真实一个都没裁掉
Partition
Condition: true
Parts: 20/20 ← 真实一个都没裁掉
PrimaryKey
Condition: true
Parts: 20/20每一步都是本文上面用真实EXPLAIN indexes=1跑出来的原始结果。
EXPLAIN indexes=1