背景
最近有一个场景,需要大批量处理几千w的数据,之前是按照分页查询的方式来处理,但是会导致查到最后越来越慢,想到流式查询 和游标查询 。游标查询的方式,可能对数据库性能影响比较大,本次测试就不考虑了。 jvm参数设置 由于本地测试,机器内存比较大,为了测试效果,于是将jvm设置小一点
-ea -Xms512M -Xmx512m
普通查询
@Test
public void testCommonQuery(){
tmpFeeService.commonQuery();
}
@Override
public void commonQuery() {
list();
}
一次性查询所有的数据到,无疑会导致oom
### Error querying database. Cause: java.sql.SQLException: GC overhead limit exceeded
流式查询
@Test
public void testStreamQuery(){
***Service.streamQuery();
}
@Override
public void streamQuery() {
***Mapper.streamQuery(new ResultHandler<TmpFee>() {
@Override
public void handleResult(ResultContext<? extends ***> resultContext) {
*** = resultContext.getResultObject();
log.info("处理查询出的结果:{}",***.getBizId());
}
});
}
@Select("select * from ***")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE)
@ResultType(***.class)
void streamQuery(ResultHandler<TmpFee> tmpFeeResultHandler);
JVM也非常稳定
普通分页查询
@Override
public void commonPageQuery()
int pageNum = 1;
int pageSize = 10000;
List<***> list;
int size = 0;
do{
list= ***.lambdaQuery().page(new Page<>(pageNum, pageSize, false)).getRecords();
if (CollUtil.isNotEmpty(tmpFee)){
log.info("处理一批数据");
}else {
continue;
}
size += ***.size();
pageNum++;
}while (Objects.equals(list.size(),pageSize));
log.info("处理........{}条", size);
时间上没有区别,内存也是比较稳定的
参考
关于流式查询以及游标查询和普通查询的对比
|