MyBatis读取大量数据(流式读取)

说明

导出大量数据时,虚拟机频繁GC,内存耗尽,CPU爆满

场景:java端从数据库读取100W数据进行后台业务处理

方案

可采用Mybatis数据流式读取进行优化

  1. 分页读取出来。缺点:需要排序后分页读取,性能低下。
  2. 一次性读取出来。缺点:需要很大内存,一般计算机不行。
  3. 建立长连接,利用服务端游标,一条一条流式返回给java端。
  4. jdbc中有个重要的参数fetchSize(它对业务实现无影响,即不会限制读取条数等),优化后可显著提升性能。

内容

JDBC三种读取方式:

  1. 一次全部(默认):一次获取全部。

  2. 流式:多次获取,一次一行。

  3. 游标:多次获取,一次多行。

  4. Mapper层

    <select id="exportAll" resultType="jjche.demo.modules.student.vo.StudentVO" resultSetType="FORWARD_ONLY"
            fetchSize="-2147483648">
        SELECT * FROM students
    </select>
  1. Dao层
void exportAll(ResultHandler<StudentVO> handler);
  1. Service层
this.baseMapper.exportAll(resultContext -> {
            StudentVO studentVO = resultContext.getResultObject();
            list.add(studentVO);
        });

原理分析

  1. 先在服务端执行查询后将数据缓存在服务端。(耗时相对较长)
  2. java端获取数据时,利用服务端游标进行指针跳动,如果fetchSize为1000,则一次性跳动1000条,返回给java端缓存起来。(耗时较短,跳动次数为N/1000)
  3. 在调用next函数时,优先从缓存中取数,其次执行2过程。(内存读取,耗时可忽略)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容