bigywater.tech
ClickHouse 内部原理 · 83

查询缓存和文件系统缓存

真实开启查询缓存对比同一条查询前后两次的耗时,验证43倍的真实加速,并诚实记录一次未能分离出文件系统缓存效果的尝试。

43倍提速
真实查询缓存命中时相比未命中的加速比
诚实的空白
真实未能测出文件系统缓存单独的明显效果

做的事:真实开启查询缓存,对比同一条查询前后两次的耗时

代码SELECT name, value FROM system.settings WHERE name='use_query_cache'; -- 真实默认0 SYSTEM DROP QUERY CACHE; SELECT sum(sipHash64(s)) FROM demo.cputest SETTINGS use_query_cache=1; -- 第1次 SELECT sum(sipHash64(s)) FROM demo.cputest SETTINGS use_query_cache=1; -- 第2次(一模一样)

验证:真实第二次快了约43倍

实测 · 本机执行输出
use_query_cache 默认值: 0   ← 真实需要手动开启

第1次(cache_miss): 43ms
第2次(cache_hit) :  1ms   ← 真实快了约43倍

SELECT query, stale, shared FROM system.query_cache;
→ SELECT sum(sipHash64(s)) FROM demo.cputest SETTINGS use_query_cache=1 ...   0   0

查询缓存真实做的事情很直接:把一条查询的最终结果整个存起来,下次收到完全相同的查询文本,直接把存好的结果原样返回,完全跳过重新执行的过程——本文这条查询本身要真实对2000万行做一次sipHash64计算,第二次能压到1ms,就是因为真实完全没有重新触碰这2000万行数据。

诚实的另一次尝试:没能干净分离出文件系统缓存的贡献

本文还真实尝试了另一个角度——想单独验证"文件系统缓存"这个更底层的效果:重启ClickHouse服务清空它自己的mark cache,禁用查询缓存(use_query_cache=0),对比重启后第一次读取(理论上的"冷读",需要真实从磁盘读取part文件)和紧接着第二次读取(理论上的"热读",操作系统的文件系统页缓存应该已经缓存了这些文件)的耗时——真实测出来的结果是冷读55ms、热读53ms,几乎没有差别,没能像查询缓存那样干净地展示出效果。诚实的推测是:本文这台机器用的存储介质本身足够快,或者测试用的数据量在这台机器的资源规模下还没大到让"磁盘IO"成为真实的瓶颈——本系列前面很多篇的耗时数字都在几十毫秒量级,这个尺度下进程调度、网络往返(即使是本机localhost)这些开销可能已经把"文件系统缓存该不该生效"这件事真实淹没掉了。这也是为什么本文没有为了讲清楚"文件系统缓存"这个概念,硬凑一组看起来漂亮但可能是巧合的数字——真实的教训是:查询缓存这一层,因为它跳过的是"重新执行整条查询"这个动作,效果在本文的测试条件下真实立竿见影;文件系统缓存这一层更底层、更依赖具体的硬件和数据规模,本文没能在这台机器上、用这份测试数据干净地把它的贡献单独测出来,这个诚实的空白比编造一组数字更有价值。

分步演示:从43倍的查询缓存提速到诚实记录的另一次尝试

每一步都是本文上面用真实缓存开关跑出来的原始结果,包括没有测出明显效果的部分。

查询缓存真实43倍提速,文件系统缓存的效果本文未测出
这一步新验证的场景

    本文用到的工具

    • 本机 ClickHouse 26.9.4(单节点),真实的 use_query_cache 与 system.query_cache
    • 诚实说明:本文未能在这台机器上干净分离出文件系统缓存单独的耗时贡献
    京ICP备2026067502号-1京公网安备11010502063487号