当前位置:   article > 正文

面试:如何通过 MyBatis 查询千万数据并保证内存不溢出?_mybatis查询40w数据

mybatis查询40w数据

在这里插入图片描述

由于现在 ORM 框架的成熟运用,很多小伙伴对于 JDBC 的概念有些薄弱,ORM 框架底层其实是通过 JDBC 操作的 DB

JDBC(JavaDataBase Connectivity)是 Java 数据库连接, 说的直白点就是使用 Java 语言操作数据库

由 SUN 公司提供出一套访问数据库的规范 API, 并提供相对应的连接数据库协议标准, 然后 各厂商根据规范提供一套访问自家数据库的 API 接口

文章大数据量操作核心围绕 JDBC 展开,目录结构如下:

  • MySQL JDBC 大数据量操作
    • 常规查询
    • 流式查询
    • 游标查询
    • JDBC RowData
    • JDBC 通信原理
  • 流式游标内存分析
    • 单次调用内存使用
    • 并发调用内存使用
  • MyBatis 如何使用流式查询
  • 结言

MySql JDBC 大数据量操作


整篇文章以大数据量操作为议题,通过开发过程中的需求引出相关知识点

  1. 迁移数据
  2. 导出数据
  3. 批量处理数据

一般而言笔者认为在 Java Web 程序里,能够被称为大数据量的,几十万到千万不等,再高的话 Java(WEB 应用)处理就不怎么合适了


举个例子,现在业务系统需要从 MySQL 数据库里读取 500w 数据行进行处理,应该怎么做

  1. 常规查询,一次性读取 500w 数据到 JVM 内存中,或者分页读取
  2. 流式查询,建立长连接,利用服务端游标,每次读取一条加载到 JVM 内存
  3. 游标查询,和流式一样,通过 fetchSize 参数,控制一次读取多少条数据

微信搜索【源码兴趣圈】,关注龙台,回复【资料】领取涵盖 GO、Netty、SpringCLoud Alibaba、Seata、开发规范、面试宝典、数据结构等电子书 or 视频学习资料!


常规查询

默认情况下,完整的检索结果集会将其存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于 MySQL 网络协议的设计,因此更易于实现

假设单表 500w 数据量,没有人会一次性加载到内存中,一般会采用分页的方式

@SneakyThrows
@Override
public void pageQuery() {
    @Cleanup Connection conn = dataSource.getConnection();
    @Cleanup Statement stmt = conn.createStatement();
    long start = System.currentTimeMillis();
    long offset = 0;
    int size = 100;
    while (true) {
        String sql = String.format("SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM YOU_TABLE LIMIT %s, %s", offset, size);
        @Cleanup ResultSet rs = stmt.executeQuery(sql);
        long count = loopResultSet(rs);
        if (count == 0) break;
        offset += size;
    }

    log.info("  
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/721918
推荐阅读
相关标签