ClickHouse:SQL筛选与聚合语义
前置:WHERE、GROUP BY及金额口径。文中的六行数据和p2_clickhouse.events来自完整事件工程的DDL、CSV与查询。适用:单节点ClickHouse 24.8 LTS基础语法;资料核对2026-10-17。示例未执行,本轮仅静态解析和文本审阅,不连接数据库、启动服务或调用产品接口。
ClickHouse 时间筛选
ClickHouse 时间筛选使用半开区间表达开始包含、结束排除,UTC边界与表类型一致。筛1月用大于等于1月1日且小于2月1日,可自然衔接相邻月份,避免“最后一秒”的精度假设。先写过滤,再GROUP BY,最后对输出ORDER BY;建表排序不保证查询结果输出有序。
本例限定tenant_id=7且1月时间窗,符合条件的金额是10.00、15.50、4.50,总额30.00。CN占25.50,US占4.50。查询可写为下列SQL;对业务日界线有其他约定时,应先转换明确的边界,而非混用服务器本地日期。
SELECT country, count() AS n, sum(amount) AS amount
FROM p2_clickhouse.events
WHERE tenant_id=7
AND event_time >= toDateTime('2026-01-01 00:00:00','UTC')
AND event_time < toDateTime('2026-02-01 00:00:00','UTC')
GROUP BY country ORDER BY country;ClickHouse 聚合口径
ClickHouse 聚合口径由GROUP BY维度和输入行集合决定;count统计行而非业务唯一事件,重复输入会改变sum与count。把event_id加入GROUP BY仅改变输出粒度,并不自动判断哪条版本有效。若业务要求去重收入,必须先定义逻辑键和版本选择,再计算金额,不能把uniqExact(event_id)与原始sum混在一起就称为正确账单。
六行基线总额60.00;重复导入第一条事件后总额70.00、行数7。此时uniqExact(event_id)=6仍成立,但sum已经重复10.00。COUNT与SUM分母、币种、退款符号、时间范围要同时一致。本课负金额被CHECK拒绝,所以退款应另行建模,不能把这份模型直接移用到净收入。
练习:两批平均金额分别10与100,行数分别9与1,能否取平均55?解答:总额190除以10得到19。可组合聚合应保留sum和count,或者保留avgState并用avgMerge;不能平均平均值。
ClickHouse 查询计划
ClickHouse 查询计划用EXPLAIN查看过滤条件、索引和读取范围,再用实际查询日志核对读取行数与字节。计划展示可使用哪些裁剪,不是运行耗时证明;表只有六行时,即使计划显示主键条件,也可能读取全部所在granule。因此学习索引不能只观察最终返回三行。
练习SQL是EXPLAIN indexes=1后接租户与月份sum查询。记录选中的parts、granules、过滤表达式,并和取消tenant_id条件的计划比较。若排序键首列不在条件中,后续时间列未必能同样有效地减少读取;实际效果取决于数据分布和索引条件。
工程上还需保留同一数据量、冷热缓存、并发与配置条件。read_rows、read_bytes、memory_usage能说明工作量,单一耗时不能解释瓶颈。不要用LIMIT 10当作必定只扫描十行的承诺,尤其是排序和聚合仍需处理更多输入。
官方依据与范围
中文与英文MergeTree、ReplacingMergeTree对照核对;翻译或当前文档包含的新功能不自动适用于24.8。本课没有运行该版本,只有静态证据。旧文ClickHouse概述保留原URL与正文,旧容量描述不作为本课性能结论。
继续阅读
- 引擎、导入与聚合
- 引擎、导入与聚合
- 完整事件项目