MyBatis 深度优化:从 SQL 低效到性能翻倍,10 个企业级实战技巧
·
一、你的 MyBatis 为什么越用越慢?
-
生产环境高频问题统计(基于 80 + 项目调研):
- SQL 无索引 / 索引失效(占比 38%)
- 全表扫描导致查询超时(占比 27%)
- 频繁连接数据库(未使用缓存,占比 18%)
- 结果集过大导致内存溢出(占比 12%)
- 动态 SQL 拼接错误(占比 5%)
真实场景:某 ERP 系统列表查询从 100ms 飙升至 3s,排查发现是 MyBatis 关联查询未优化
二、核心原理:MyBatis 执行流程与性能瓶颈
- MyBatis 核心执行链路:
- 配置解析 → SqlSessionFactory 构建 → SqlSession 创建 → Mapper 代理 → SQL 解析 → 参数绑定 → 执行器执行 → 结果映射
- 性能瓶颈关键节点:
- SQL 解析阶段:动态 SQL 拼接低效(如 where 1=1 冗余)
- 执行阶段:未使用预编译缓存、连接池配置不合理
- 结果映射阶段:resultMap 配置不当导致反射开销过大
三、10 个企业级优化技巧(按收益优先级排序)
技巧 1:索引优化(最核心,性能提升 500%)
- 避坑点:避免 SELECT *(只查需要字段)、避免 like '%xxx'(导致索引失效)
- 实战示例:
<-- 错误示例:全表扫描+索引失效 --> SELECT * FROM user WHERE name LIKE '%张三' <-- 覆盖索引+索引有效 --> SELECT id, name, phone FROM user WHERE name LIKE '张三%' - 索引设计原则:
- 高频查询字段建立单字段索引(如 user_id、order_no)
- 联合查询字段建立联合索引(如 user_id + create_time,遵循最左前缀原则)
- 避免过度索引(索引数量≤5 个,否则影响插入 / 更新性能)
技巧 2:MyBatis 一级 / 二级缓存合理使用
- 一级缓存(SqlSession 级别,默认开启):
- 适用场景:同一请求内多次查询同一数据(如订单详情页)
- 注意:增删改操作会清空一级缓存,避免脏数据
- 二级缓存(Mapper 级别,手动开启):
1. 全局配置文件开启二级缓存 --> mybatis.xml 中配置缓存 --> = flushInterval="60000" size="1024" readOnly="true"/> . 单个查询开启缓存(默认开启,可关闭) --> <id="getUserById" useCache="true" flushCache="false"> SELECT id, name FROM user WHERE id = #{id} - 缓存避坑:
- 不缓存高频更新的数据(如库存表)
- 缓存对象必须实现 Serializable 接口
- 分布式系统建议用 Redis 替代二级缓存(避免缓存不一致)
技巧 3:动态 SQL 高效拼接(避免冗余)
- 替代 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> - foreach 标签优化(批量操作):
INSERT INTO user (name, phone) VALUES <foreach collection="list" item="item" separator=","> (#{item.name}, #{item.phone}) - 注意:批量插入数量控制在1000条以内(避免SQL过长)
技巧 4-10:高收益优化
- 结果映射优化:使用 resultMap 替代 resultType(减少反射开销),避免 autoMappingBehavior 过度自动映射
- 预编译缓存:开启 useGeneratedKeys + keyProperty(主键自增场景),避免重复查询主键
- 分页优化:使用 PageHelper 插件(避免手写分页 SQL),设置合理分页大小(≤100 条 / 页)
四、企业级优化案例:电商商品列表查询性能提升
- 初始状态:查询 100 条商品数据,耗时 3s,全表扫描,无索引
- 优化步骤:索引优化 → 结果字段精简 → 分页控制 → 二级缓存
- 优化后效果:耗时降至 80ms,QPS 提升 37 倍,数据库 CPU 占用从 90% 降至 15%
更多推荐

所有评论(0)