第 11 章 · TTL、分区与数据生命周期

四个交互演示:① 分区裁剪可视化 · ② TTL 数据搬迁动画 · ③ 列 / 表 / GroupBy TTL 对比 · ④ 分区粒度选择器

分区裁剪:让 WHERE 命中分区键,跳过整个目录

下面是 12 个月分区的 events_log,每个分区约 1 亿行。试试不同 WHERE 条件,看 ClickHouse 跳过哪些分区。

WHERE event_date AND
点 "🔍 扫描" 看裁剪效果...
陷阱演示:选 "toString(event_date) =",你会看到 所有分区都被扫描 —— 因为函数包了一层,CK 没法把字符串反推回 toYYYYMM 范围。WHERE 写表达式时,永远让分区键在 = / >= / BETWEEN 的左边。

TTL 多温度搬迁:SSD → HDD → S3 → 删除

表配置如下:

CREATE TABLE events_log (...)
TTL event_date + INTERVAL 30  DAY  TO DISK   'cold',
    event_date + INTERVAL 60  DAY  RECOMPRESS CODEC(ZSTD(17)),
    event_date + INTERVAL 90  DAY  TO VOLUME 's3_volume',
    event_date + INTERVAL 365 DAY  DELETE
SETTINGS storage_policy = 'hot_to_cold_to_s3';

🔥 hot (NVMe SSD)

0~30 天,每 GB ¥3

♨️ warm (HDD + ZSTD17)

30~90 天,每 GB ¥0.3

❄️ cold (S3)

90~365 天,每 GB ¥0.03

🗑 deleted

> 365 天,物理删除
SSD 0~30d
HDD 30~60d
HDD+ZSTD 60~90d
S3 90~365d
删除 >365d
关键: TTL 不是 cron。它在后台 Merge 时被检查。这就是为什么按下"⏩ 快进"之后还要"🔧 触发 Merge"才看到搬迁动画。
记忆口诀:"TTL 不到点不动,到点了不 Merge 还是不动。" 想立即生效用 OPTIMIZE TABLE ... FINALMATERIALIZE TTL

三种 TTL 形态对比:表级 / 列级 / GROUP BY 聚合

① 表级 TTL: DELETE

TTL event_date + INTERVAL 7 DAY DELETE

7 天后整行消失。

dateuidpayload

② 列级 TTL: SET

debug_log TTL event_date + INTERVAL 7 DAY

7 天后该列变空,行还在,其他列保留。

dateuidpayloaddebug_log

③ GROUP BY TTL: rollup

TTL event_date + INTERVAL 30 DAY
GROUP BY event_date, user_id
SET cnt = sum(cnt)

30 天后明细按 (date,uid) 合并成一行。

dateuidcnt
选哪个?
  • 过期数据完全没用 → 表级 DELETE
  • 核心数据要留,附加调试字段过期 → 列级 SET
  • 明细过期但聚合还要留 → GROUP BY rollup(CK 独家本事)

分区粒度选择器:粒度 vs Part 数 vs Merge 压力

假设业务:每天 1 亿行,保留 90 天,单批 INSERT 10 万行 / 5 秒。

小批量 → 每次形成新 Part → 容易爆炸
活跃 Part 总数
Merge 压力 (后台合并队列长度估算)
DROP 粒度灵活性
查询裁剪精度
口诀:"1~10 亿行/分区 是甜蜜区。Part 总数超 1000 报警,超 3000 写入会被节流(parts_to_throw_insert)。"