首页/数据/NoSQL 速查/投影 projection 加速查询
ClickHouse56 条

投影 projection 加速查询

投影为表预先维护一份按某查询模式组织的隐藏数据集(含不同排序或预聚合结果),优化器在匹配到查询时自动改用投影,无需改 SQL。

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

投影 projection 是什么

投影是 ClickHouse 为表预先维护的一份按特定查询模式组织的隐藏数据集:可以换一种排序方式,也可以预先算好聚合结果。查询命中匹配条件时,优化器会自动改用投影,SQL 完全不用改。它把开销转移到写入与合并阶段,因此是「写多读少」与「读多写少」之间的一个可调旋钮。

基本信息

适用平台ClickHouse MergeTree 家族(较新版本支持)
定义ALTER TABLE t ADD PROJECTION p (SELECT … GROUP BY … ORDER BY …)
物化MATERIALIZE PROJECTION 回填已有数据;新写入的数据自动维护
开关optimize_use_projections 默认开启,可会话级关闭做对照测试
查看system.projections 与 EXPLAIN 确认投影是否被采用
代价每个投影都会随写入同步维护,投影越多写入与合并越重

典型使用场景

  • 固定聚合查询:看板长期按同一维度分组统计,用投影把聚合结果预先算好
  • 排序键切换:同一份数据既按时间又按用户查询,用投影提供第二种顺序
  • 明细表上的高频过滤:为常用过滤列建投影,避免每次全量扫描
  • 替代物化视图的灵活方案:投影随原表管理,不必维护独立的写入链路
  • 试运行验证:先建投影观察查询是否真的改用它,再决定是否保留

定义与验证

定义与验证
-- 定义投影:按用户与日期预先聚合,另带一份有序数据集
ALTER TABLE events
ADD PROJECTION proj_user_day
(
    SELECT user_id, toDate(ts) AS d, count() AS cnt
    GROUP BY user_id, d
);

-- 已有数据需要显式回填,新写入自动维护
ALTER TABLE events MATERIALIZE PROJECTION proj_user_day;

-- 查询书写方式不变,优化器自动选择投影
SELECT user_id, toDate(ts) AS d, count()
FROM events GROUP BY user_id, d;

-- 用 EXPLAIN 确认读取的是投影而不是原表
EXPLAIN SELECT user_id, toDate(ts) AS d, count() FROM events GROUP BY user_id, d;

机制对照

机制作用点适用判断
投影表内隐藏数据集,随原表写入维护查询模式固定、希望不改 SQL
物化视图独立目标表,写入时触发计算需要跨表加工或独立管理目标表
跳过索引granule 级摘要,只跳块不重排条件选择性高、数据有一定有序性
排序键调整改变主索引与物理顺序查询模式单一且长期稳定
投影本质是用写入与存储换查询速度:用 EXPLAIN 确认查询确实使用了投影,若优化器没选中,多半是聚合粒度或字段与投影定义不完全匹配。
投影数量要克制:每一个都会在写入时同步维护,过多投影会让合并变慢、写入放大显著,新增前先量化收益。

易错点

  • 以为建了投影就自动生效:查询的聚合粒度与字段顺序不匹配时优化器不会采用,必须用 EXPLAIN 验证
  • 忘记 MATERIALIZE:历史数据仍在原表里,只有新写入的数据参与投影,统计结果出现缺口
  • 投影堆得太多:写入路径上的维护成本叠加,合并压力上升,反而拖慢整体写入
  • 把投影当作实时更新的缓存:它随数据写入同步维护,不解决跨表关联与复杂加工的时效问题,那类需求适合独立链路

数据来源与参考

  • ClickHouse Docs: Projections
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌