最近碰到sql查询出错的问题,原因即是OOM(out of memory 内存溢出),GC回收内存查询GC limited expeed问题,为此给出几种方案比较;
1 普通查询
原始mybatis语句:
select from user_messages
where created_time between '2018-01-01' and '${currentYear}-12-31'
and DATEDIFF(#{date,jdbcType=VARCHAR},created_time)=0
对于普通sql查询,上面写法足以满足需求,Mybatis作为一个优秀的ORM框架极大方便了我们对数据库CUID的操作,但是Mybatis对底层JDBC的封装同时也给我们底层调优带来了一些问题。当一次查询数据过多,比如1000W条数据得场景,就会出现OOM,这个时候JDBC可能采用返回游标的方式就可以完成。Oracle和MySQL在服务器端已经帮我们完成游标偏移,这样也使得客户端可以用较少内存来处理数据库返回的数据,下面介绍流式查询。
2 流式查询
将普通查询改为流式查询,本质是Mybatis提供了回调ResultHandler方式可以完成数据逐条访问,这种方式在大数据量场景非常有用,可以均衡系统复杂性和系统资源占用两个因素。
改造前:
//DAO层
public interface DataMapper {
List getAllUsers();
}
//mapper xml :
select FUND_ACCOUNT from fundacco