Ignite 2.15中SQL统计总记录数与getCacheSize API结果不一致问题
select count(*)与getCacheSize结果不一致的排查与解决 以下是针对该问题的常见原因及对应解决办法:
SQL统计依赖过期元数据
Ignite的select count(*)默认优先使用主键索引的统计元数据(需开启统计自动收集),这类元数据是定期更新的,并非实时同步。而getCacheSize()直接读取缓存当前的实际记录数(含内存、磁盘存储条目),数据频繁增删时,统计元数据未及时更新就会导致偏差。
解决:执行ANALYZE TABLE [表名]手动刷新表统计信息,再重新执行count(*)对比。过期数据清理延迟
getCacheSize()会包含已过期但尚未被清理的条目,而SQL查询默认过滤过期数据(查询时会检查TTL)。若缓存的过期/驱逐任务未触发,就会出现计数差异。
解决:调用cache.localEvict(null)(本地节点)或cache.globalEvict(null)(全局节点)手动触发清理,或等待自动清理任务执行后再对比。分布式缓存的计数逻辑差异
若为分布式缓存/分区表:- 若调用
localSize()获取本地节点计数,必然和SQL全局count(*)不一致; - 即使调用全局
size(),Ignite计算全局大小时可能存在短暂一致性延迟,而SQLcount(*)若不依赖统计元数据则是实时扫描分区数据。
解决:调用cache.size(CachePeekMode.ALL)获取全局所有节点的缓存大小;执行select count(*) from [表名] /*+ FORCE_INDEX(PRIMARY) */强制扫描主键索引,避免使用过时统计数据。
- 若调用
隐式/显式缓存配置差异
通过SQL创建的隐式缓存与手动创建的显式缓存可能存在配置差异(如统计收集开关、持久化模式),导致计数逻辑不一致。
解决:检查表对应缓存的statisticsEnabled参数(默认开启,确认未被修改),同时验证CacheStore配置一致性,避免存储层与缓存层计数偏差。脏数据/重复键问题
若缓存中存在重复键条目(如并发写入未处理主键冲突),getCacheSize()会统计所有条目,而SQL因主键约束仅返回唯一记录,导致计数不一致。
解决:执行select _key, count(*) from [表名] group by _key having count(*) > 1排查重复键,清理脏数据后再对比。
内容的提问来源于stack exchange,提问作者Choco

