SQL 语句完全一致时将命中缓存。
需求场景 & 解决方案
见 缓存概览 文档。
设计原理
SQLCache 按 SQL 的签名、查询的表的分区 ID、分区最新版本来存储和获取缓存。三者组合确定一个缓存数据集,任何一个变化了,如 SQL 有变化,如查询字段或条件不一样,或数据更新后版本变化了,会导致命中不了缓存。
如果多张表 Join,使用最近更新的分区 ID 和最新的版本号,如果其中一张表更新了,会导致分区 ID 或版本号不一样,也一样命中不了缓存。
SQLCache,更适合 T+1 更新的场景,凌晨数据更新,首次查询从 BE 中获取结果放入到缓存中,后续相同查询从缓存中获取。实时更新数据也可以使用,但是可能存在命中率低的问题。
当前支持 OlapTable 内表 和 Hive 外表。
使用方式
确保 fe.conf 的 cache_enable_sql_mode=true(默认是 true)
vim fe/conf/fe.conf
cache_enable_sql_mode=true
在 MySQL 命令行中设置变量
MySQL [(none)]> set [global] enable_sql_cache=true;
注:global 是全局变量,不加指当前会话变量
在2.1.3及以上版本,Nereids优化器在fe的内存中保存缓存的关键信息,比如非确定函数及其评估值,在关键信息未发生变化时可以跳过sql解析,优化了sql cache的查询速度。
可以通过fe配置项sql_cache_manage_num和expire_sql_cache_in_fe_second来控制这些关键信息的个数以及淘汰时间来减少对fe的内存消耗。
MySQL [(none)]> ADMIN SET FRONTEND CONFIG ('sql_cache_manage_num' = '100');
MySQL [(none)]> ADMIN SET FRONTEND CONFIG ('expire_sql_cache_in_fe_second' = '300');
缓存条件
第一次查询后,如果满足下面三个条件,查询结果就会被缓存。
(当前时间 - 查询的分区最后更新时间) 大于 fe.conf 中的 cache_last_version_interval_second。
查询结果行数 小于 fe.conf 中的 cache_result_max_row_count。
查询结果 bytes 小于 fe.conf 中的 cache_result_max_data_size。
具体参数介绍和未尽事项见 query-cache.md。
未尽事项
SQL 中包含产生随机值的函数,比如 random(),使用 QueryCache 会导致查询结果失去随机性,每次执行将得到相同的结果。
类似的 SQL,之前查询了 2 个指标,现在查询 3 个指标,是否可以利用 2 个指标的缓存?目前不支持