数据库大数据量处理方法启用游标查询 1,可以防止数据库一下返回过大,导致OOM,超时(超过数据库限制),效果类似分页查询 2,需要开启事务---分批查询的缘故
大数据量查询:
1,使用游标查询---避免内存泄漏 mybatis-plus在一次查询量超过百万级别的时候,容易出现内存泄漏,此时可以使用游标查询,逐条查询(查询完就释放内存 fetchSize = 100000 每次获取的条数,获取完就释放),并且在游标关闭的时候也会释放游标本身即最后一次查询的内存
2,使用流式查询---避免内存泄漏 3,要加@Transactional否则报游标关闭
@Transactional @Override public List<HHDto> getHNoPage(HRequest hRequest) { List<HH> result = new ArrayList<>(); List<HH> resultTmp = new ArrayList<>(); List<HHDto> resultDto = new ArrayList<>(); List<Long> matchingIds = hRequest.getMatchingId(); Long segmentId = hRequest.getSegmentId(); Long lastId = hRequest.getLatestId(); Long begin = hRequest.getBegin(); Long limit = hRequest.getLimit(); Integer taskType = hRequest.getTaskType(); String taskId = hRequest.getTaskId(); Cursor<HH> domainList =null; try{ QueryWrapper<HH> query = new QueryWrapper<>(); if(null != matchingIds && matchingIds.size()>0){ query.in("m",matchingIds); } if(null !=segmentId){ query.eq("s",segmentId); } if(null != begin && null != limit){ query.gt("id",begin); query.last("limit "+limit); } if(null !=taskType){ query.eq("t",taskType); } if(null !=taskId){ query.eq("t_id",taskId); } MyExport myExport = new MyExport(); domainList = HHMapper.listData(query,myExport); Iterator<HH> iter = domainList.iterator(); int num=0; while (iter.hasNext()){ // HH tmp =iter.next(); rebuildBo(resultDto, iter.next()); // result.add(tmp); num++; } if(num == 0){ log.info("没有对应条件的查询结果:sid:{},mid:{}",sId,mIds); }else{ log.info("getHNoPage数据库查询结果数:{}",num); }
result =null;
}catch (Exception e){ log.error("根据mId查询HH失败,条件:{},异常:{}",mIds,e.getMessage(),e); }finally { if (null != domainList) { try { domainList.close(); } catch (Exception e) { log.error("根据matchIngId查询HH游标关闭失败:{}",e.getMessage(), e); } } } return resultDto; }
import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler;