ClickHouse如何从正在运行的查询中获取结果数据?
ClickHouse 重复大查询结果复用方案
原生ClickHouse 没有提供直接读取正在运行查询返回结果的语法,也就是不存在你提到的select * from running_query where query_id = 'id_of_slow_query'这类直接拿运行中查询结果的用法,但针对你提到的多用户同时执行相同大查询的场景,有成熟的替代方案可以实现相同的效果,避免重复计算浪费资源:
- 方案1:启用查询结果缓存
ClickHouse 21.3及以上版本内置了查询结果缓存功能,完全匹配你的使用场景。开启后第一个大查询执行完成后,后续所有完全相同的查询请求会直接命中缓存返回结果,不需要重新执行。
你可以选择全局开启该功能,也可以在单次查询中指定开启,写法如下:
SELECT 你的大查询逻辑 SETTINGS use_query_cache = true;
缓存会自动在底层数据更新、或者过期后自动失效,不需要额外维护。
- 方案2:显式指定查询ID复用物化结果
如果你需要通过query_id显式绑定查询结果,可以将大查询逻辑标记为物化CTE,配合异步查询使用:
第一个执行查询的用户运行:
WITH big_query_result AS MATERIALIZED ( -- 这里写你的大查询逻辑 ) SELECT * FROM big_query_result SETTINGS async_query = 1, query_id = 'id_of_slow_query';
后续其他用户只需要执行相同的查询语句,或者查询该query_id对应的物化结果,就可以直接拿到已经计算完成的返回数据,不需要重复执行大查询。
- 方案3:落地中间结果表
如果大查询的逻辑固定,你可以新增一张中间结果表,定时或者触发式将大查询的结果写入该表,所有用户直接查询这张小的中间结果表即可,全量用户只需要付出一次大查询的计算成本。
补充:如果你需要判断指定query_id的查询是否已经执行完成,可以查询系统表
system.processes,语法为SELECT * FROM system.processes WHERE query_id = 'id_of_slow_query',查询结果为空就代表该查询已经执行结束,可以去获取对应结果。
内容的提问来源于stack exchange,提问作者Qimb
相关产品推荐
相关产品推荐

