Query Cache
StarRocks 提供的 Query Cache 特性,可以帮助您极大地提升聚合查询的性能。开启 Query Cache 后,每次处理聚合查询时,StarRocks 都会将本地聚合的中间结果缓存于内存中。这样,后续收到相同或类似的聚合查询时,StarRocks 就能够直接从 Query Cache 获取匹配的聚合结果,而无需从磁盘读取数据并进行计算,大大节省查询的时间和资源成本,并提升查询的可扩展性。在大量用户同时对复杂的大数据集执行相同或类似查询的高并发场景下,Query Cache 的优势尤为明显。
该特性从 2.5 版本开始在存算一体集群中支持,并从 3.4 版本开始在存算分离集群中支持。
在 2.5 版本,Query Cache 仅支持宽表模型下的单表聚合查询。自 3.0 版本起,除宽表模型下的单表聚合查询外,Query Cache 还支持星型模型下简单多表 JOIN 的聚合查询。
应用场景
Query Cache 可以生效的典型应用场景有如下特点:
- 查询多为宽表模型下的单表聚合查询或星型模型下简单多表 JOIN 的聚合查询。
- 聚合查询以非 GROUP BY 聚合和低基数 GROUP BY 聚合为主。
- 查询的数据以按时间分区追加的形式导入,并且在不同时间分区上的访问表现出冷热性。
目前 Query Cache 支持的查询需要满足下面条件:
-
查询的执行引擎为 Pipeline。
说明
除 Pipeline 以外的其他执行引擎不支持 Query Cache。
-
查询的表为原生 OLAP 表(自 2.5 版本起支持)或存算分离表(自 3.0 版本起支持)。不支持外表上的查询。查询计划中,实际访问的是同步物化视图时,Query Cache 也可以生效。异步物化视图暂不支持。
-
查询为单表聚合查询或多表 JOIN 的聚合查询。
说明
- Query Cache 支持 Broadcast Join 和 Bucket Shuffle Join。
- Query Cache 支持含 Join 算子的两种树形:先聚合后 Join 和 先 Join 后聚合。在先聚合后 Join 的树形结构中,不支持 Shuffle Join。在先 Join 后聚合的树形结构中,不支持 Hash Join。
-
查询不包含
rand
、random
、uuid
和sleep
等不确定性 (Nondeterminstic) 函数。
Query Cache 支持全部数据分区策略,包括 Unpartitioned、Multi-Column Partitioned 和 Single-Column Partitioned。
产品边界
- Query Cache 依赖于 Pipeline 执行引擎的 Per-Tablet 计算。Per-Tablet 计算是指一个 Pipeline Driver 能够以 Tablet 为单位对整 Tablet 进行处理,而不是每次只处理一个 Tablet 的一部分、或者通过交叉并发的方式同时处理多个 Tablet。如果单个 BE 所访问的 Tablet 的数量大于等于实际调用的 Pipeline Driver 的数量(即,实际并发度)时,则启用 Query Cache。如果单个 BE 所访问的 Tablet 的数量小于 Pipeline Driver 的数量,则每个 Pipeline Driver 只会处理某个 Tablet 的一部分数据,无法形成 Per-Tablet 的计算结果,这种情况下不启用 Query Cache。
- 在 StarRocks 中,一个聚合查询至少包含四个阶段的聚合。在一阶段聚合中,只有当 OlapScanNode 和 AggregateNode 位于同一个 Fragment 时,AggregateNode 产生的 Per-Tablet 计算结果才会缓存。在其他阶段聚合中,AggregateNode 产生的Per-Tablet 计算结果不会缓存。部分 DISTINCT 聚合查询,受会话变量
cbo_cte_reuse
为true
影响,当执行计划中生产数据的 OlapScanNode 和消费数据的一阶段 AggregateNode 位于不同的 Fragment、并且中间通过 ExchangeNode 传输数据时,也不启用 Query Cache。比如如下两个场景里,采用 CTE 优化,不启用 Query Cache:- 查询的输出列包含聚合函数
avg(distinct)
。 - 查询的输出列含多个 DISTINCT 聚合函数。
- 查询的输出列包含聚合函数
- 如果在聚合之前对数据进行了 Shuffle 操作,则 Query Cache 无法加速对该数据的查询。
- 如果表的分组列或去重列是高基数列 (High-Cardinality Column),则对该表执行聚合查询生成的结果会很大。这类查询会在运行时绕过 Query Cache。
- Query Cache 的存储占用 BE 的少量内存,默认缓存大小为 512 MB,因此不宜缓存较大的数据项。此外,在启用 Query Cache 的情况下,如果缓存的命中率低,则会带来性能惩罚。因此,在查询的计算过程中,如果某一个 Tablet 上的计算结果大小超过了
query_cache_entry_max_bytes
或query_cache_entry_max_rows
参数指定的阈值,则该查询接下来的计算不再开启 Query Cache,转而触发使用 Passthrough 机制来执行。