ClickHouse 慢查询怎么分析?我做了一个 EXPLAIN 可视化 + AI 调优助手
摘要:ClickHouse 的 EXPLAIN 输出格式多、层次深,排查慢查询时往往要在终端、文档和 system.query_log 之间来回切换。本文介绍在线工具ClickHouse EXPLAIN 可视化 & AI 调优助手,支持离线粘贴执行计划、直连集群采集指标,并结合 AI 给出优化建议。
在线体验:https://ch.charunion.com
关键词:ClickHouse、EXPLAIN、慢查询、SQL 优化、执行计划、query_log、AI 调优
一、为什么 ClickHouse 的 EXPLAIN 这么难读?
做过 ClickHouse 性能优化的同学,大概都经历过这样的场景:
EXPLAINPLANSELECTevent_type,count()AScnt,uniq(user_id)ASuvFROMdemo.eventsWHEREevent_date>=today()-7GROUPBYevent_typeORDERBYcntDESC;终端里吐出来的是一棵树:
Expression (Project names) Sorting (ORDER BY cnt DESC) Expression ((Before ORDER BY + Projection)) Aggregating Expression (WHERE) ReadFromMergeTree (demo.events) → 68,432 rows, 0.12s看着还行?但当 SQL 变复杂、节点变多、再叠加 EXPLAIN PIPELINE、EXPLAIN JSON 时,问题就来了:
- 格式不统一:文本树、JSON、Pipeline 描述,解析难度差很多
- 缺少运行时数据:EXPLAIN 告诉你「打算怎么扫」,但真实读了多少行、耗时多久,还得去 system.query_log 里翻
- 优化靠经验:看到 Aggregating 知道要警惕,但具体该改索引、分区还是上物化视图,往往要查文档 + 问同事
- 协作成本高:把终端截图发给 DBA,对方还要你补 DDL、表结构、业务 SLA
我日常也在用 ClickHouse,被这些问题折腾久了,索性做了一个 Web 工具,把执行计划可视化、指标采集、规则诊断、AI 对话串成一条链路。
二、工具能做什么?
在线地址:https://ch.charunion.com
| 能力 | 说明 |
|---|---|
| 执行计划树 | 把 EXPLAIN 文本/JSON 解析成可折叠的树形结构 |
| 多 EXPLAIN 类型 | 支持 PLAN、PIPELINE、QUERY TREE、AST、SYNTAX |
| 离线 / 连接双模式 | 可粘贴已有结果,也可直连 ClickHouse 自动执行 |
| 运行时指标 | 连接模式下关联 query_log,展示真实扫描行数、耗时 |
| AI 调优助手 | 结合 SQL、DDL、执行计划上下文,对话式给优化建议 |
主界面分为输入区和结果区,结果区用 Tab 组织:
- 概览:关键指标汇总(扫描行数、耗时、分析深度等)
- 执行计划:树形展示,扫描节点可挂载运行时数据
- 诊断:基于规则的初步问题识别
- 优化建议:结构化优化项(索引、分区、改写方向等)
- AI 助手:针对当前 SQL 上下文的多轮对话
配图建议:首页整体截图、执行计划树展开截图
三、两种使用方式
3.1 离线模式(无需连接数据库)
适合:
- 生产环境不方便开外网连接
- 已经有一份 EXPLAIN 结果,想快速解读
- 内网审计严格,只能手动复制粘贴
操作步骤:
- 选择「离线模式」
- 粘贴 SQL
- 选择 EXPLAIN 类型(默认 PLAN)
- 粘贴 EXPLAIN 输出结果
- (可选)补充表 DDL,提升 AI 分析质量
- 点击「开始分析」
工具内置了 demo.events 的示例数据,第一次使用可以直接点「加载示例」体验。
3.2 连接模式(自动采集)
适合:
- 测试环境 / 开发集群
- 需要真实 query_log 指标
- 想一键跑 EXPLAIN,不想手动复制
操作步骤:
- 选择「连接模式」
- 填写 ClickHouse 地址、端口、用户名、库名
- 可选开启:
- 拉取 query_log:关联最近一次执行的运行时指标
- 执行 SQL(只读):在服务端执行 SELECT 并采集 live 指标(需谨慎开启)
- 点击「开始分析」
注意:连接模式下,凭证只用于本次分析请求,请勿在生产只读账号未隔离的情况下随意开启「执行 SQL」。
四、一个完整的分析示例
以如下 SQL 为例:
SELECTevent_type,count()AScnt,uniq(user_id)ASuvFROMdemo.eventsWHEREevent_date>=today()-7GROUPBYevent_typeORDERBYcntDESC;对应表结构:
CREATETABLEdemo.events(event_dateDate,event_timeDateTime,user_id UInt64,event_type String,properties String)ENGINE=MergeTree()PARTITIONBYtoYYYYMM(event_date)ORDERBY(event_date,event_time,user_id);4.1 从执行计划看什么?
树形结构里,重点关注叶子扫描节点(如 ReadFromMergeTree):
- 预估/实际扫描行数
- 是否命中分区裁剪
- 聚合、排序是否发生在扫描之后(常见性能瓶颈)
中间节点如 Expression、Distinct 往往不直接产生 IO,指标显示为—是正常现象。
4.2 结合 query_log 看什么?
如果开启了 query_log 采集,可以看到:
- read_rows / read_bytes
- query_duration_ms
- memory_usage
EXPLAIN 是计划,query_log 是结果。两者对照,才能判断是「计划就不优」还是「数据分布变了导致计划失效」。
4.3 AI 助手怎么用?
在 AI Tab 里可以直接问:
- 7 天窗口能否再缩小?
- uniq 和 count 哪个更适合这个场景?
- 要不要按 event_date 做预聚合?
- 帮我改写一版更清晰的 SQL
AI 会基于当前 SQL、DDL、执行计划摘要来回答,比裸聊 GPT 更贴近 ClickHouse 语境。
五、后端实现的几处关键点
工具采用Next.js 14 + FastAPI前后端分离架构,后端通过 clickhouse-connect 访问 ClickHouse,MySQL 存储用户与历史记录。
5.1 EXPLAIN 解析:文本 vs JSON
ClickHouse 不同版本的 EXPLAIN 输出差异很大,实践中至少处理了三类情况。
(1)缩进文本树(最常见)
Aggregating Expression (WHERE) ReadFromMergeTree (demo.events)按缩进层级还原父子关系即可。
(2)JSON 格式
EXPLAIN JSON 返回嵌套对象,需要递归 unwrap,把 Plan、Expression、Description 等字段统一映射到内部树节点。
(3)多棵候选树打分
有些输出会解析出多个候选结构,通过打分函数选最合理的一棵,避免 JSON 被误解析成无意义的扁平结构。
5.2 运行时指标 enrichment
解析出计划树后,对 ReadFromMergeTree 等扫描节点,尝试从以下来源 enrichment:
- 连接模式 live 指标:执行后即时采集
- query_log 匹配:按 query_id / 时间窗口匹配最近一次执行记录
这样树上不再只有「计划」,而是「计划 + 实际」对照。
5.3 分析深度
系统会根据输入完整度标记 analysis_depth:
- 只有 EXPLAIN 文本 → preliminary(初步分析)
- 有 DDL + query_log → 更深入的综合诊断
5.4 架构简图
┌─────────────┐ HTTPS ┌─────────────┐ │ Next.js │ ─────────────► │ FastAPI │ │ Web 前端 │ │ 后端 API │ └─────────────┘ └──────┬──────┘ │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ ClickHouse MySQL Cursor AI API (EXPLAIN/query_log) (用户/历史) (调优对话)六、部署与使用说明
- 前端:https://ch.charunion.com
- 后端 API:https://ch-api.charunion.com/api/v1
使用权限:
- 访客:可直接使用分析功能(离线/连接模式)
- 登录用户:可使用历史记录、AI 助手等需持久化的功能
本地 Docker 部署也支持,核心编排为 docker-compose.prod.yml,前端构建时需注入 NEXT_PUBLIC_API_URL 等环境变量。
七、适用场景与局限
适合
- ClickHouse SQL 日常 Review
- 慢查询初步定位(先看计划,再看 log)
- 新人学习 EXPLAIN 的可视化教具
- 和 DBA / 同事分享分析结果(比终端截图清晰)
当前局限
- AI 建议需人工审核,不能直接等同于生产变更方案
- 复杂分布式场景下,query_log 匹配偶有偏差
- 连接模式依赖网络可达,生产集群建议优先离线模式
- 中间算子节点暂不支持完整运行时指标(聚焦扫描节点)
八、写在最后
ClickHouse 的性能优化,从来不是看一眼 EXPLAIN 就能结束的。它是一套「看懂计划 → 对照运行时 → 结合表结构 → 验证改写」的流程。
这个工具的目标,就是把这条链路尽量压缩到一个页面里:
粘贴 SQL → 看到树 → 看到指标 → 得到建议 → 继续追问 AI
如果你也在做 ClickHouse 查询优化,欢迎试用:https://ch.charunion.com
有任何问题或功能建议,欢迎在评论区交流。
