主题
ClickHouse 面试题总索引
从 0 到 1 学习 ClickHouse 教程配套的 面试题导航页。 每条只列「题目 + 章节链接 + 难度」,详细答案在各章末尾的「面试高频题」小节。
总览
- 总题数:约 110 题(19 章章节题 + 30 题大厂真题速记)
- 难度标识:
- ⭐ 基础:写过 SQL 就能答
- ⭐⭐ 入门:理解 OLAP 基础概念
- ⭐⭐⭐ 中级:掌握 MergeTree / MV / 向量化
- ⭐⭐⭐⭐ 进阶:懂副本/分布式/调优
- ⭐⭐⭐⭐⭐ 高阶:架构师 / 源码级
按主题分类
1. ClickHouse 基础与定位(OLAP / 列存 / 向量化)
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 1 | OLAP 与 OLTP 的本质区别是什么?为什么同一条 SQL 在 CK 上能比 MySQL 快 100 倍? | 第 1 章 | ⭐⭐ |
| 2 | 行存 vs 列存在物理布局上长什么样?聚合查询为何天然偏爱列存? | 第 1 章 | ⭐⭐ |
| 3 | 向量化执行是什么?为什么「一次算 1024 行」比「逐行处理」快? | 第 1 章 | ⭐⭐⭐ |
| 4 | ClickHouse 在 Doris / Druid / StarRocks 家族中的生态位是什么? | 第 1 章 | ⭐⭐⭐ |
| 5 | LZ4 / ZSTD / Delta / DoubleDelta 压缩编码各自适合什么场景? | 第 1 章 | ⭐⭐⭐ |
| 6 | ClickHouse 不适合哪些场景?举出至少 3 个 | 第 1 章 | ⭐⭐ |
2. 客户端与基础 SQL
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 7 | clickhouse-client / HTTP(8123) / JDBC 三种入口有什么区别?什么场景用哪个? | 第 2 章 | ⭐⭐ |
| 8 | ClickHouse 的 SQL 方言与标准 SQL 最大的 3 个差异是什么? | 第 2 章 | ⭐⭐ |
| 9 | FORMAT 全家桶(JSONEachRow / Parquet / Native / CSV ...)各自用途 | 第 2 章 | ⭐⭐ |
| 10 | SYSTEM RELOAD / SYSTEM FLUSH LOGS / SYSTEM STOP MERGES 各起什么作用? | 第 2 章 | ⭐⭐⭐ |
| 11 | SHOW / DESCRIBE 命令怎么查表结构、分区、Part、Merge 进度? | 第 2 章 | ⭐⭐ |
3. 数据类型与表引擎
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 12 | LowCardinality 原理是什么?为什么能加速查询?用在高基数列反而更慢,为什么? | 第 3 章 | ⭐⭐⭐ |
| 13 | Nullable 为何多一倍空间?生产上怎么替代? | 第 3 章 | ⭐⭐⭐ |
| 14 | Array / Map / Nested / Tuple 分别对应什么存储布局? | 第 3 章 | ⭐⭐⭐ |
| 15 | Decimal vs Float64:金额为什么不能用 Float? | 第 3 章 | ⭐⭐ |
| 16 | AggregateFunction 与 SimpleAggregateFunction 区别?什么时候用哪个? | 第 3 章 | ⭐⭐⭐⭐ |
| 17 | MergeTree / Log / Memory / Distributed / Kafka 5 大类引擎如何选型? | 第 4 章 | ⭐⭐⭐ |
| 18 | 为什么 Memory 引擎不适合做缓存表?重启就没了,那它存在的意义是什么? | 第 4 章 | ⭐⭐ |
4. MergeTree 家族与稀疏索引(灵魂)
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 19 | MergeTree 的 Part 目录里都有哪些文件?Mark / Granule / primary.idx 三者怎么配合? | 第 5 章 | ⭐⭐⭐⭐ |
| 20 | PRIMARY KEY / ORDER BY / PARTITION BY 三者可以完全一样吗?最佳实践? | 第 5 章 | ⭐⭐⭐ |
| 21 | index_granularity = 8192 为什么是这个值?改大改小各有什么后果? | 第 5 章 | ⭐⭐⭐ |
| 22 | Skip Index minmax / set / bloom_filter / ngrambf_v1 的选型与失效条件 | 第 5 章 | ⭐⭐⭐⭐ |
| 23 | 为什么 ClickHouse 的主键不保证唯一?和 MySQL 主键有本质区别? | 第 5 章 | ⭐⭐⭐ |
| 24 | Merge 过程是什么?什么情况下触发?为什么它是 ClickHouse 的灵魂? | 第 5 章 | ⭐⭐⭐ |
| 25 | ReplacingMergeTree 什么时候做去重?FINAL 为什么慢? | 第 6 章 | ⭐⭐⭐⭐ |
| 26 | SummingMergeTree vs AggregatingMergeTree:都能预聚合,选哪个? | 第 6 章 | ⭐⭐⭐ |
| 27 | CollapsingMergeTree 和 VersionedCollapsingMergeTree 的行折叠原理 | 第 6 章 | ⭐⭐⭐⭐ |
| 28 | AggregateFunction(uniqExact, UInt64) 列到底存的是什么?为什么不能直接 SELECT 出来看? | 第 6 章 | ⭐⭐⭐⭐ |
5. 写入与查询优化
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 29 | 为什么 ClickHouse 要求「大批量写」?小批写的后果是什么? | 第 7 章 | ⭐⭐⭐ |
| 30 | async_insert 原理是什么?它能完全替代 Buffer 引擎吗? | 第 7 章 | ⭐⭐⭐ |
| 31 | Buffer 引擎什么场景下仍然值得用?它的刷盘策略是什么? | 第 7 章 | ⭐⭐⭐ |
| 32 | max_threads / max_memory_usage / max_insert_block_size 分别控制什么? | 第 7 章 | ⭐⭐⭐ |
| 33 | INSERT ... SELECT vs CSV 批量导入:性能差距在哪? | 第 7 章 | ⭐⭐ |
6. 聚合、窗口与数组
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 34 | uniqExact / uniq / uniqHLL12 / uniqCombined 4 个去重函数该怎么选? | 第 8 章 | ⭐⭐⭐ |
| 35 | quantile / quantileTDigest / quantileExact 误差与性能对比 | 第 8 章 | ⭐⭐⭐ |
| 36 | argMax / argMin / anyLast 各自在时序场景怎么用? | 第 8 章 | ⭐⭐⭐ |
| 37 | ARRAY JOIN 做的是什么?它和 LATERAL VIEW 类似吗? | 第 8 章 | ⭐⭐⭐ |
| 38 | 窗口函数 sum() OVER (...) 在 CK 里的实现与 MySQL 有什么不同? | 第 8 章 | ⭐⭐⭐ |
7. JOIN 与字典
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 39 | ClickHouse 的 JOIN 算法默认是什么?大表 JOIN 为什么容易 OOM? | 第 9 章 | ⭐⭐⭐⭐ |
| 40 | ANY / ASOF / GLOBAL JOIN 各自的语义与适用场景 | 第 9 章 | ⭐⭐⭐⭐ |
| 41 | 为什么生产推荐用 Dictionary 替代小维度表的 JOIN?它的查找复杂度是多少? | 第 9 章 | ⭐⭐⭐ |
| 42 | Dictionary 的 HASHED / FLAT / COMPLEX_KEY_HASHED / IP_TRIE 布局各自的用途 | 第 9 章 | ⭐⭐⭐⭐ |
| 43 | grace_hash / partial_merge JOIN 算法什么时候能救命? | 第 9 章 | ⭐⭐⭐⭐ |
8. 物化视图与 Projection(灵魂)
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 44 | ClickHouse 的 MV 是「定时刷新」还是「INSERT 触发」?它看到的是什么? | 第 10 章 | ⭐⭐⭐⭐ |
| 45 | POPULATE 有什么致命缺陷?生产应该怎么初始化历史数据? | 第 10 章 | ⭐⭐⭐⭐ |
| 46 | 链式 MV 的坑:中间某层报错会导致什么?如何排查? | 第 10 章 | ⭐⭐⭐⭐ |
| 47 | Projection 与 MV 的本质区别?什么时候选 Projection? | 第 10 章 | ⭐⭐⭐⭐ |
| 48 | AggregatingMergeTree + MV 搭实时 UV 的完整写法(白板题) | 第 10 章 | ⭐⭐⭐⭐⭐ |
| 49 | xxxState / xxxMerge / xxxMergeState 三兄弟怎么用? | 第 10 章 | ⭐⭐⭐⭐ |
9. TTL、分区、Mutation
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 50 | PARTITION BY toYYYYMMDD vs toYYYYMM:一般怎么选?粒度太细有什么后果? | 第 11 章 | ⭐⭐⭐ |
| 51 | TTL ... DELETE / TO VOLUME / TO DISK 分别做了什么? | 第 11 章 | ⭐⭐⭐ |
| 52 | OPTIMIZE TABLE ... FINAL 为什么生产基本不用?它到底做了什么? | 第 11 章 | ⭐⭐⭐⭐ |
| 53 | ALTER TABLE ... UPDATE/DELETE 是同步还是异步?怎么查进度? | 第 12 章 | ⭐⭐⭐⭐ |
| 54 | Lightweight DELETE 和传统 Mutation 的区别?它是真的删了吗? | 第 12 章 | ⭐⭐⭐⭐ |
| 55 | REPLACE PARTITION / DROP PARTITION / DETACH PARTITION 的典型用法 | 第 12 章 | ⭐⭐⭐ |
10. 副本与分布式(灵魂)
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 56 | ReplicatedMergeTree + Keeper 的副本同步流程:Part 是怎么流转的? | 第 13 章 | ⭐⭐⭐⭐⭐ |
| 57 | Distributed 引擎写入 vs 读取的 fan-out / fan-in 链路是什么样? | 第 13 章 | ⭐⭐⭐⭐ |
| 58 | internal_replication = true / false 配错会导致什么后果? | 第 13 章 | ⭐⭐⭐⭐ |
| 59 | 分片键怎么选?rand() / cityHash64(user_id) / 自增 ID 各有什么权衡? | 第 13 章 | ⭐⭐⭐⭐ |
| 60 | ClickHouse Keeper 与 ZooKeeper 的关系?为什么 CK 官方推荐自研 Keeper? | 第 13 章 | ⭐⭐⭐⭐ |
| 61 | 单机 CK 如何演进到 3 分片 × 2 副本集群?给出迁移路径 | 第 13 章 | ⭐⭐⭐⭐⭐ |
11. 运维与生态
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 62 | Kafka 引擎消费延迟如何排查?关键配置 kafka_num_consumers / kafka_max_block_size | 第 14 章 | ⭐⭐⭐⭐ |
| 63 | MaterializedPostgreSQL / MaterializedMySQL 怎么玩的?生产能不能直接依赖? | 第 14 章 | ⭐⭐⭐⭐ |
| 64 | S3 表函数 / S3 引擎 / storage_policy 冷盘,如何做分层? | 第 14 章 | ⭐⭐⭐⭐ |
| 65 | CK 的权限模型:Profile / Quota / Row Policy 怎么搭配? | 第 15 章 | ⭐⭐⭐ |
| 66 | 如何防止一个用户写坏 SQL 拖死整个实例?(关键参数) | 第 15 章 | ⭐⭐⭐ |
| 67 | EXPLAIN PLAN / PIPELINE / ESTIMATE 各自输出什么?怎么看得懂? | 第 16 章 | ⭐⭐⭐⭐ |
| 68 | 慢查询定位 4 步曲:query_log → text_log → trace_log → 火焰图 | 第 16 章 | ⭐⭐⭐⭐ |
| 69 | system.parts / system.mutations / system.replication_queue 最该盯哪些字段? | 第 16 章 | ⭐⭐⭐ |
| 70 | BACKUP / RESTORE 与 clickhouse-backup 的关系?生产怎么做热备? | 第 17 章 | ⭐⭐⭐ |
| 71 | 升级 CK 版本要注意哪些 Settings 兼容问题?回滚预案? | 第 17 章 | ⭐⭐⭐⭐ |
| 72 | Prometheus + Grafana 监控 CK 的必备面板有哪些? | 第 17 章 | ⭐⭐⭐ |
| 73 | SQL UDF / Executable UDF 区别?它们的执行成本 | 第 18 章 | ⭐⭐⭐ |
| 74 | clickhouse-local 和 chdb 在什么场景下替代 CK Server? | 第 18 章 | ⭐⭐⭐ |
12. 综合项目与场景题
| # | 题目 | 章节 | 难度 |
|---|---|---|---|
| 75 | 给你 10 亿/天的埋点,要求秒级大屏,怎么建表? | 第 19 章 | ⭐⭐⭐⭐⭐ |
| 76 | 为什么大屏查询走聚合表而不是明细表?明细不是很快吗? | 第 19 章 | ⭐⭐⭐⭐ |
| 77 | Kafka → CK 端到端延迟主要花在哪?怎么压到 1 秒内? | 第 19 章 | ⭐⭐⭐⭐ |
| 78 | 上线后 Part 数暴涨怎么应急 + 长期治理? | 第 19 章 | ⭐⭐⭐⭐⭐ |
| 79 | 亿级留存查询 OOM,有哪些优化路径? | 第 19 章 | ⭐⭐⭐⭐ |
| 80 | 项目从 ClickHouse 迁 Doris,你会怎么设计双写过渡? | 第 19 章 | ⭐⭐⭐⭐⭐ |
大厂真题速记 30 题(面试前夜扫一遍)
题目 + 一句话答案。不确定的再跳回对应章节看详解。
| # | 题目 | 一句话答案 |
|---|---|---|
| 1 | ClickHouse 为什么快? | 列存 + 向量化 + 稀疏索引 + 后台合并,I/O 少、CPU 用满、JIT 友好。 |
| 2 | MergeTree 的 Part 由哪些文件组成? | 每列一个 .bin + .mrk,加 primary.idx / columns.txt / checksums.txt / partition.dat 等。 |
| 3 | 稀疏索引跳 Granule 的核心前提? | 数据按排序键有序。WHERE 必须命中排序键前缀。 |
| 4 | ReplacingMergeTree 是严格去重吗? | 不是。只有同一 Part / 同一次 Merge 内才保证去重,跨 Part 要 FINAL。 |
| 5 | FINAL 为什么慢? | 查询时必须把所有 Part 里同主键行汇到一起去重,本质是在线 Merge。 |
| 6 | SummingMergeTree 会汇总字符串吗? | 不会。默认只汇总数值列;可通过 engine 参数指定汇总列。 |
| 7 | AggregatingMergeTree 存的是什么? | 聚合的 state 二进制(如 HyperLogLog bitmap),查询时必须 xxxMerge 才正确。 |
| 8 | uniqExact 和 uniq 区别? | Exact 精确但内存 O(N);uniq 是 HyperLogLog 约 0.5% 误差、内存 O(1)。 |
| 9 | LowCardinality 原理? | 列级字典编码:实际存 UInt8/16 索引 + 共享字典,基数 ≤ 万级时非常省。 |
| 10 | Nullable 为什么贵? | 额外维护一个 .null.bin 位图,打碎向量化优化。 |
| 11 | MV 是什么本质? | 焊在源表上的 INSERT 触发器,只看本次 INSERT 的 Block。 |
| 12 | POPULATE 的坑? | populate 过程中源表新写入不会进入 MV,会丢数据。 |
| 13 | Projection 和 MV 的区别? | Projection 是表内 alternative physical layout,查询自动选择;MV 是独立的目标表。 |
| 14 | 分布式表写入为什么可能重复? | internal_replication=false + ReplicatedMergeTree 组合时会重复写。 |
| 15 | Distributed 是存数据的表吗? | 不是。它只是路由器,真实数据在本地表。 |
| 16 | Keeper 和 ZooKeeper 选哪个? | 新集群一律选 ClickHouse Keeper(RAFT + 更低延迟)。 |
| 17 | OPTIMIZE TABLE ... FINAL 生产能用吗? | 小范围(单分区)偶尔可用;全表 FINAL 严禁,等同于 DDOS 自己。 |
| 18 | Mutation 是同步还是异步? | 异步。下发即返回,后台重写 Part,system.mutations 查进度。 |
| 19 | Lightweight DELETE 原理? | 加一列 _row_exists 位图标记,不立即重写,查询端过滤。 |
| 20 | Buffer 引擎什么时候还值得用? | 需要「写前攒批 + 可查最新数据」的特殊场景;崩了会丢。 |
| 21 | async_insert 崩了会丢数据吗? | 默认可能丢。需 wait_for_async_insert=1 或持久化 async 队列。 |
| 22 | 大表 JOIN OOM 怎么办? | 字典替代 / GLOBAL JOIN / grace_hash / 小表放右 / 预聚合。 |
| 23 | ASOF JOIN 什么场景? | 时序对齐:价格变动表对订单表按时间就近匹配。 |
| 24 | 为什么 CK 不适合 OLTP? | 无行级锁、无 MVCC、UPDATE/DELETE 是异步重写,并发小事务极差。 |
| 25 | 时区列怎么处理? | 用 DateTime64(3, 'Asia/Shanghai');不要存 UInt32 timestamp。 |
| 26 | system.query_log 保留多久? | 默认无限(按 TTL 设置),生产建议加 TTL 保留 14~30 天。 |
| 27 | 单机 Part 数警戒线? | 活跃 Part > 10000 / 单分区 > 300 必须排查。 |
| 28 | Kafka 消费延迟常见原因? | kafka_num_consumers 太小、单次 Block 太大、目标表 Merge 压力大、网络抖动。 |
| 29 | CK 适合与 Flink 配合吗? | 适合写入侧做流式 ETL;最简单是 Flink → Kafka → CK Kafka 引擎。 |
| 30 | 面试必背 3 句话? | 列存让扫描少、向量化让 CPU 满、MergeTree让写入快且后台合并有序。 |
使用指南
- 系统学:按章节顺序做题,每题先自答再对章末答案。
- 突击用:直接扫「大厂真题速记 30 题」,不熟的再跳章节详解。
- 白板题:重点是第 10、13、19 章的架构题,画图为主。
📌 教程配套附录请看:
appendix_cheatsheet.md·appendix_ck_vs_mysql.md·appendix_pitfalls.md