一、你的 MyBatis 为什么越用越慢?​

  1. 生产环境高频问题统计(基于 80 + 项目调研):​

  • SQL 无索引 / 索引失效(占比 38%)​
  • 全表扫描导致查询超时(占比 27%)​
  • 频繁连接数据库(未使用缓存,占比 18%)​
  • 结果集过大导致内存溢出(占比 12%)​
  • 动态 SQL 拼接错误(占比 5%)​

真实场景:某 ERP 系统列表查询从 100ms 飙升至 3s,排查发现是 MyBatis 关联查询未优化​

二、核心原理:MyBatis 执行流程与性能瓶颈​

  1. MyBatis 核心执行链路:​
    1.  配置解析 → SqlSessionFactory 构建 → SqlSession 创建 → Mapper 代理 → SQL 解析 → 参数绑定 → 执行器执行 → 结果映射​            
  2. 性能瓶颈关键节点:​
  • SQL 解析阶段:动态 SQL 拼接低效(如 where 1=1 冗余)​
  • 执行阶段:未使用预编译缓存、连接池配置不合理​
  • 结果映射阶段:resultMap 配置不当导致反射开销过大​

三、10 个企业级优化技巧(按收益优先级排序)​

技巧 1:索引优化(最核心,性能提升 500%)​

  1. 避坑点:避免 SELECT *(只查需要字段)、避免 like '%xxx'(导致索引失效)​
  2. 实战示例:​
     <-- 错误示例:全表扫描+索引失效 -->
     SELECT * FROM user WHERE name LIKE '%张三'
    
    
    <-- 覆盖索引+索引有效 -->
     SELECT id, name, phone FROM user WHERE name LIKE '张三%'
  3. 索引设计原则:​
  • 高频查询字段建立单字段索引(如 user_id、order_no)​
  • 联合查询字段建立联合索引(如 user_id + create_time,遵循最左前缀原则)​
  • 避免过度索引(索引数量≤5 个,否则影响插入 / 更新性能)​

技巧 2:MyBatis 一级 / 二级缓存合理使用​

  1. 一级缓存(SqlSession 级别,默认开启):​
  • 适用场景:同一请求内多次查询同一数据(如订单详情页)​
  • 注意:增删改操作会清空一级缓存,避免脏数据​
  1. 二级缓存(Mapper 级别,手动开启):​
     1. 全局配置文件开启二级缓存 -->
     mybatis.xml 中配置缓存 -->
    = flushInterval="60000" size="1024" readOnly="true"/>
    
    . 单个查询开启缓存(默认开启,可关闭) -->
     <id="getUserById" useCache="true" flushCache="false">
        SELECT id, name FROM user WHERE id = #{id}
  2. 缓存避坑:​
  • 不缓存高频更新的数据(如库存表)​
  • 缓存对象必须实现 Serializable 接口​
  • 分布式系统建议用 Redis 替代二级缓存(避免缓存不一致)​

技巧 3:动态 SQL 高效拼接(避免冗余)​

  1. 替代 where 1=1 的优雅方案:​
    冗余且低效    
    SELECT id, name FROM user WHERE 1=1​
    <if test="name != null">AND name = #{name}</if>​
    <if test="age != null">AND age = #{age}</if>
    
    修改为
    SELECT id, name FROM user​ 
    <where>
    <if test="name != null">AND name = #{name}</if>​
    <if test="age != null">AND age = #{age}</if>
    </where>
  2. foreach 标签优化(批量操作):​
    INSERT INTO user (name, phone) VALUES
    <foreach collection="list" item="item" separator=",">
           (#{item.name}, #{item.phone})
         
    - 注意:批量插入数量控制在1000条以内(避免SQL过长)

技巧 4-10:高收益优化

  1. 结果映射优化:使用 resultMap 替代 resultType(减少反射开销),避免 autoMappingBehavior 过度自动映射​
  2. 预编译缓存:开启 useGeneratedKeys + keyProperty(主键自增场景),避免重复查询主键​
  3. 分页优化:使用 PageHelper 插件(避免手写分页 SQL),设置合理分页大小(≤100 条 / 页)​

四、企业级优化案例:电商商品列表查询性能提升​

  1. 初始状态:查询 100 条商品数据,耗时 3s,全表扫描,无索引​
  2. 优化步骤:索引优化 → 结果字段精简 → 分页控制 → 二级缓存​
  3. 优化后效果:耗时降至 80ms,QPS 提升 37 倍,数据库 CPU 占用从 90% 降至 15%
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐