调用GridDB的query.fetch()是否会将全部查询结果集加载到内存中?
GridDB Java客户端fetch方法行为说明
你调用query.fetch()时默认会一次性将所有匹配行全部加载到JVM内存中,不属于遍历RowSet时才拉取的懒加载模式,这就是你调用该方法后内存占用立刻大幅上涨的直接原因。
GridDB Java客户端的无参fetch()方法的默认逻辑是向服务端发起查询请求后,等待服务端返回全部符合条件的结果,将所有行数据反序列化后存储到客户端本地内存,再将封装了全量数据的RowSet对象返回。20万行传感器数据一次性加载到内存会产生明显的内存占用涨幅,当结果集规模达到百万级及以上时,甚至会直接触发JVM内存溢出。
如果你需要处理大结果集,建议使用以下两种方案降低内存占用:
- 调用带参数的
fetch(boolean allowPartial)重载方法,传入true开启分段加载模式:
该模式下不会一次性拉取全量结果,会按照客户端配置的分批大小,在你遍历RowSet的过程中按需从服务端拉取对应批次的数据,内存占用只会维持在单批结果的量级。
示例代码如下:Query<RowSet<Row>> query = container.query("SELECT * FROM sensor_data"); // 传入true开启分段加载,支持大结果集低内存处理 RowSet<Row> rs = query.fetch(true); while (rs.hasNext()) { Row row = rs.next(); // 业务逻辑处理单行数据 } - 对于超大规模结果集,可以在查询语句中搭配
LIMIT和OFFSET语法做主动分页,逐页查询逐页处理,完全自主控制每次拉取的数据量。
注意:开启分段加载时请尽量在获取
RowSet后立即遍历处理,不要长时间持有未遍历完成的RowSet对象,避免占用服务端的查询会话资源。
内容的提问来源于stack exchange,提问作者subhash sah
相关产品推荐
相关产品推荐

