一说到 ClickHouse 的快,谈的最多的是它的向量化执行,而在最近一次 ClickHouse Meetup 中,ClickHouse 团队的 Maksim Kita 为我们带来了关于JIT 优化的分享。
其实在 ClickHouse 中,有同时用到向量化执行和 JIT (just-in-time compilation) 的。
JIT 带来的好处很多,例如:
1. 有助于提升L1、L2缓存命中
2. 减少执行的代码
3. 更好的利用编译器优化
4. 直接使用目标CPU指令
等等
既然提到的好处这么多,说的我都想跃跃欲试了,接下来就让我们就看看 JIT 是否能够提升性能吧。
例如执行下面的语句,并开启JIT:
代码语言:javascript复制SELECT a b c FROM test_jit
settings min_count_to_compile_expression=1,compile_expressions=1;
日志中会多出一段 JIT 的内容:
代码语言:javascript复制 <Trace> ExpressionJIT: Compile expression plus(plus(UInt64, UInt64), UInt64)
这是将表达式部分,原本的 DAG 进行了优化:
咱们继续验证,执行下面的语句,强制关闭JIT:
代码语言:javascript复制SELECT
number * 2
number * 3
number * 4
number * 5
FROM numbers(10000000)
FORMAT Null
settings min_count_to_compile_expression=1,compile_expressions=0;
Query id: 2bf9d8a4-d7cb-4691-9246-b890dd0f1b36
Ok.
0 rows in set. Elapsed: 0.055 sec. Processed 10.02 million rows, 80.18 MB (180.95 million rows/s., 1.45 GB/s.)
然后开启JIT,再执行一次:
代码语言:javascript复制SELECT
number * 2
number * 3
number * 4
number * 5
FROM numbers(10000000)
FORMAT Null
settings min_count_to_compile_expression=1,compile_expressions=1;
Query id: 154a0af2-bd62-4ab6-89bb-dbebafce16eb
Ok.
0 rows in set. Elapsed: 0.016 sec. Processed 10.02 million rows, 80.18 MB (630.94 million rows/s., 5.05 GB/s.)
对比上面上次查询的效率:
开启 JIT 是 (630.94 million rows/s., 5.05 GB/s.)
关闭 JIT 是 (180.95 million rows/s., 1.45 GB/s.)
两者相差 3.5 倍,提效确实很明显。
好了,现在总结一下:
- ClickHouse 利用 JIT 对查询的 表达式步骤 和 聚合步骤 进行提速;
- 支持优化的表达式有:
- 一元运算,如abs
- 二元运算,如 、-、*、/
- 逻辑运算,如 and、or
- 分支判断,如 if、multiIf
- 位移操作,如bitShiftLeft
- ClickHouse 利用 JIT 将表达式的执行性能普遍提升了 1.5 ~ 3倍,特殊情况可以达到 20倍; 聚合步骤的性能普遍提升了 1 ~ 2倍
- 表达式优化将在 21.6 Release 版本中默认支持
- 聚合阶段的优化会在 21.8 or 21.9 Release中默认支持
好了,今天的分享就到这里吧,原创不易,如果这篇文章对你有帮助,欢迎 点赞、转发、在看 三连击