
ClickHouse 的 system.query_log 是分析慢查询的核心系统表,但默认字段多、时间跨度大、噪音高,直接查容易迷失。关键不是“查全”,而是快速定位耗时高、频率高、资源消耗大的异常查询。下面给出一个实用、可复用的慢查询分析模板,聚焦真实问题场景。
筛选有效慢查询(排除干扰)
不是所有耗时长的查询都该优化——比如后台定时任务、一次性导出、或用户主动取消的查询。应先过滤出真正需要关注的记录:
-
只看成功执行的查询:
type = 'QueryFinish',排除 Cancel、Exception、Timeout 等中间状态 -
排除系统内部查询:
is_initial_query = 1,避免被SELECT * FROM system.processes这类监控语句刷屏 -
设定合理耗时阈值:例如
query_duration_ms > 5000(5秒),根据业务 SLA 调整,不盲目设 100ms -
排除空查询和元数据查询:加条件
query NOT LIKE 'SELECT%' AND query NOT LIKE 'SHOW%' AND query NOT LIKE 'DESCRIBE%'(按需补充)
聚合分析高频/高耗时查询模式
单条慢查询价值有限,重点看“哪类查询反复拖慢服务”。用 normalized query(去参数化后的指纹)做聚类:
现代商务数字机构公司网站模板是一款提供数据分析、安全咨询、市场预测、业务顾问、理财投资等服务的数字机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。
- ClickHouse 22.8+ 自动提供
normalized_query_hash和normalized_query字段;旧版本可用replaceRegexpAll(query, '\d+', '?')粗略归一化 - 按指纹聚合统计:
count() AS cnt, avg(query_duration_ms) AS avg_ms, max(query_duration_ms) AS max_ms, any(query) AS sample_query - 排序建议:
ORDER BY cnt DESC, max_ms DESC LIMIT 20—— 先看“又慢又常跑”的头号嫌疑
关联资源消耗定位瓶颈根源
耗时长 ≠ SQL 写得差。结合内存、读取量、线程等指标判断是 CPU、IO 还是内存瓶颈:
-
查内存压力:看
memory_usage(字节),超 2GB 需警惕;对比peak_memory_usage和max_memory_usage -
查扫描膨胀:
read_rows / result_rows比值过高(如 > 100)说明大量无效扫描,可能缺分区裁剪或索引 -
查并发影响:同时间段内
ProfileEvents['Query']或thread_ids数量突增,可能是小查询堆积引发排队 - 可加条件:
WHERE read_rows > 10000000 AND query_duration_ms > 3000快速抓“重读慢查”
导出可读报告(附时间窗口与上下文)
给开发或 DBA 看的报告要带上下文,不能只扔 SQL:
- 必选字段:
event_time, query_duration_ms, read_rows, written_rows, memory_usage, user, address, query - 加时间分组:
toStartOfHour(event_time) AS hour,观察是否集中在某个时段(如凌晨任务高峰) - 加客户端标识:
client_hostname, client_name, http_user_agent(若走 HTTP 接口),便于追到具体服务模块 - 示例完整查询片段:
SELECT toStartOfHour(event_time) AS hour, round(query_duration_ms, 0) AS duration_ms, read_rows, round(memory_usage / 1048576, 1) AS mem_mb, user, substring(query, 1, 120) AS query_snippet, address FROM system.query_log WHERE type = 'QueryFinish' AND is_initial_query = 1 AND query_duration_ms > 5000 AND event_time >= now() - INTERVAL 1 DAY ORDER BY duration_ms DESC LIMIT 30









