MyBatis Plus大数据量查询慢原因分析及解决

 更新时间:2025年09月21日 15:52:05   作者:night_gu  
大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次处理及配置调优

大数据量查询慢的常见原因

MyBatis Plus 在处理大数据量查询时,性能瓶颈通常出现在数据库连接、网络传输、内存消耗和结果集处理等方面。

常见问题包括全表扫描、未合理使用分页、ORM 映射开销过大等。

优化方案

合理使用分页查询

MyBatis Plus 内置分页插件(PaginationInnerInterceptor),避免一次性加载全部数据。

配置示例:

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

查询时通过 Page 对象分页:

Page<User> page = new Page<>(1, 100); // 当前页, 每页条数
userMapper.selectPage(page, null);

启用流式查询

通过 @Options 注解启用 JDBC 流式读取,减少内存占用:

@Select("SELECT * FROM large_table")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)
@ResultType(User.class)
void selectLargeData(ResultHandler<User> handler);

使用游标处理结果

结合 MyBatis 的 Cursor 逐行处理数据:

try (Cursor<User> cursor = userMapper.selectCursor(null)) {
    cursor.forEach(user -> {
        // 单行处理逻辑
    });
}

SQL 语句优化

添加必要的索引,避免 SELECT *,只查询必要字段。通过 @SqlParser 注解过滤逻辑删除等干扰:

@SqlParser(filter = true)
@Select("SELECT id, name FROM user WHERE status = 1")
List<User> selectActiveUsers();

批处理操作

插入/更新时使用 saveBatch 方法,通过 rewriteBatchedStatements=true 参数提升批量性能:

List<User> userList = ... // 大数据集合
userService.saveBatch(userList, 1000); // 每批1000条

高级方案

多数据源与读写分离

通过 @DS 注解将查询路由到从库,减轻主库压力:

@DS("slave")
@Select("SELECT * FROM read_heavy_table")
List<Record> selectReadHeavyData();

结果集二次处理

在内存充足的情况下,先通过 LIMIT 分页查询 ID,再通过 IN 查询完整数据:

-- 第一步:查询ID范围
SELECT id FROM large_table LIMIT 1000000, 1000;
-- 第二步:精确获取数据
SELECT * FROM large_table WHERE id IN (1,2,3...);

配置调优

application.yml 中调整连接池参数:

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

监控与诊断

启用 p6spy 监控实际执行的 SQL,分析慢查询日志:

<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.9.1</version>
</dependency>

配置 spy.properties 记录执行时间:

appender=com.p6spy.engine.spy.appender.Slf4JLogger
logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
customLogMessageFormat=%(executionTime) ms | %(category) | %(sql)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 在SpringBoot微服务中设置和管理多个数据库的代码示例

    在SpringBoot微服务中设置和管理多个数据库的代码示例

    在现代微服务架构中,通常需要与多个数据库交互的服务,这可能是由于各种原因,例如遗留系统集成、不同类型的数据存储需求,或者仅仅是为了优化性能,在本综合指南中,我们将探讨如何在 Spring Boot 微服务中设置和管理多个数据库连接,需要的朋友可以参考下
    2024-12-12
  • Spring外部化配置的几种技巧分享

    Spring外部化配置的几种技巧分享

    在油管上看了龙之春的一个Spring tips 视频,讲述Spring外部化配置的几种技巧,收获颇多,想拿出来给大家分享下。对spring感兴趣的朋友可以了解下本文
    2021-06-06
  • Elasticsearch配置文件选项作用详解(es7)

    Elasticsearch配置文件选项作用详解(es7)

    这篇文章主要为大家介绍了Elasticsearch配置文件选项作用详解(es7),有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Spring事务管理中的异常回滚是什么

    Spring事务管理中的异常回滚是什么

    Spring中的代码出现异常时会回滚这是大家都希望的情况,这时候可以用@Transactional这个注解放在你的方法上来进行回滚,这时候有个问题就是事务回滚是不希望你在Controller进行处理,而是在Service层来进行处理
    2023-02-02
  • ActiveMQ持久化机制代码实例

    ActiveMQ持久化机制代码实例

    这篇文章主要介绍了ActiveMQ持久化机制代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java ThreadLocal 线程本地存储工具思路详解

    Java ThreadLocal 线程本地存储工具思路详解

    文章详细介绍了Java的ThreadLocal类,包括其核心作用、定位、特性、工作原理、用法、内存泄漏风险、父子线程共享问题、线程安全边界以及与synchronized和并发容器的区别,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • file.mkdir()、file.mkdirs()和file.createNewFile()的区别

    file.mkdir()、file.mkdirs()和file.createNewFile()的区别

    本文主要介绍了file.mkdir()、file.mkdirs()和file.createNewFile()的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • RabbitMQ进阶之消息可靠性详解

    RabbitMQ进阶之消息可靠性详解

    这篇文章主要介绍了RabbitMQ进阶之消息可靠性详解,abbitmq消息的投递过程中,怎么确保消息能不丢失,这是一个很重要的问题,哪怕我们做了Rabbitmq持久化,也不能保证我们的业务消息不会被丢失,需要的朋友可以参考下
    2023-08-08
  • 基于mybatis一对多查询内层排序的问题

    基于mybatis一对多查询内层排序的问题

    这篇文章主要介绍了基于mybatis一对多查询内层排序的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • SpringBoot整合EasyExcel进行大数据处理的方法详解

    SpringBoot整合EasyExcel进行大数据处理的方法详解

    EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。本文将在SpringBoot中整合EasyExcel进行大数据处理,感兴趣的可以了解一下
    2022-05-05

最新评论