bigywater.tech
ClickHouse 内部原理 · 31

ClickHouse 聚合为什么快

真实在2000万行表上对比多线程和单线程GROUP BY的耗时差异,诚实报告加速比,并结合本系列已验证的机制说明聚合快的真实根本原因。

1.5~2倍
真实测出的多线程加速比,诚实报告而非夸大
三层机制叠加
向量化+列式存储+缓存友好哈希表才是聚合快的真实根本原因

做的事:2000万行,真实对比多线程和单线程的GROUP BY耗时

代码CREATE TABLE demo.aggtest (k UInt64, cat UInt8, v Float64) ENGINE=MergeTree ORDER BY k; INSERT INTO demo.aggtest SELECT number, number%100, number*1.5 FROM numbers(20000000); SELECT cat, sum(v), count() FROM demo.aggtest GROUP BY cat; -- 默认多线程 SELECT cat, sum(v) FROM demo.aggtest GROUP BY cat SETTINGS max_threads=1; -- 强制单线程

验证:真实的耗时对比

实测 · 本机执行输出(2000万行,GROUP BY 100个分类,本机10核)
默认多线程(max_threads=auto(10)):真实46~100毫秒(3次运行:0.10s/0.08s/0.08s)
强制单线程(max_threads=1)      :真实130~230毫秒(3次运行:0.13s/0.23s/0.14s)

真实加速比:约1.5~2倍(远不到理论上的10倍线性加速)

多线程真实带来了加速,但远没有达到核心数(10核)对应的理论线性加速——这条GROUP BY本身要处理的数据量和计算量,在2000万行、100个分类这个规模下已经足够小,线程调度、各线程结果的最终合并这些真实的固定开销,占比反而变得不可忽视。

ClickHouse聚合快的真实原因,不只是"开了多线程"

这次实测的1.5~2倍加速只是聚合快的原因之一,真实更根本的原因藏在本系列前面几篇已经验证过的机制里:一是向量化执行(本系列《Vectorized Execution》验证过,数据按批处理而不是逐行,聚合函数每次调用处理一整批而不是一行);二是列式存储——GROUP BY只需要真实读取涉及到的cat和v两列,完全不用碰表里其他列(如果有的话),本系列《行式存储和列式存储》验证过这一点对IO量的真实节省;三是聚合过程本身用的是为CPU缓存友好设计的哈希表实现,对于本文这种低基数(只有100个分类)场景,哈希表小到能完全放进CPU缓存,查找和更新的真实开销极低。多线程带来的加速是这些机制之上的锦上添花,而不是聚合快的唯一原因——这也是为什么本文单线程模式下虽然变慢了,但130~230毫秒处理2000万行依然不算慢,向量化和列式存储这两个更基础的机制在单线程下依然生效。

分步演示:从多线程加速到聚合快的完整真实原因

每一步都是本文上面用真实计时跑出来的原始结果。

多线程真实带来1.5~2倍加速,但不是唯一原因
这一步新验证的模式

    本文用到的工具

    • 本机 ClickHouse 26.9.4(单节点,10核),真实对比 max_threads=auto(10) 与 max_threads=1
    京ICP备2026067502号-1京公网安备11010502063487号