从数据集中查询100W条 数据并生成到文件中
环境:Mysql5.7 innodb
显然不能一次性数据集查询到本地
那么有两种做法
1、用limit 分页查询
在一个事务中多次分页查询 然后讲结果集交给其他处理线程写文件;使用可重复读事务隔离级别 能够保证即使在处理过程中其他事务修改插入删除了满足条件的记录 多次分页查询的数据是确定的,且并不会阻塞这些CUD操作
2、使用服务端游标;
mybatis mapper文件:
<select id="selectForwardOnly" parameterType="xxx.TblUconlTransFlowHis" resultMap="BaseResultMap" fetchSize="-2147483648">
接口声明:void selectForwardOnly(TblUconlTransFlowHis record, ResultHandler<TblUconlTransFlowHis> handler);
接口实现:
tblUconlTransFlowHisMapper.selectForwardOnly(transFlowHisKey, new ResultHandler<TblUconlTransFlowHis>() {
@Override
public void handleResult(ResultContext<? extends TblUconlTransFlowHis> resultContext) {
//写文件
//logger.debug();
logger.debug(JSONObject.toJSONString(resultContext.getResultObject()));
//list.add(resultContext.getResultObject());
}
})
fetchSize设为-2147483648(Integer.MIN_VALUE) 一开始我希望或许fetchSize能够自己指定一次从服务器端获取的数据量;发现修改fetchSize的值并没有差别;结果是MYSQL并不支持自定义fetchSize 看网上说其他大型数据库(oracl db2)是支持的;mysql使用服务器端游标只能一条一条取数据。
提一句题外话:如果接口方法参数没有声明回调函数ResultHandler ,声明
fetchSize也是没有任何作用的 依然会返回完整结果集。
使用1W条数据集实验
一次性查询整个结果集到客户端花费30S,然后写文件3S
使用游标2S后就开始有数据返回并写文件然后一共花费30S;跟预期也是符合的,当然可以数据积攒到一定量再用其他线程写,性能会再有所提升。