MyBatis 性能优化:批处理、分页、缓存与慢 SQL 定位

目标:你能把 MyBatis 的性能问题拆成"SQL 本身 + JDBC/网络 + MyBatis 使用方式"三层,并掌握可落地的优化点。

1. 性能问题先分层:不要一上来就调 MyBatis

MyBatis 慢,常见根因优先级通常是:

  1. SQL/索引设计(占大头)
  2. 连接池/网络/DB 负载
  3. MyBatis 使用方式(N+1、错误分页、批处理不当)

面试时你要体现"先定位再优化"的工程能力。

2. N+1 问题:最常见的 ORM 性能坑

典型场景:

  • 查主表 N 条,再对每条查一次明细表
  • 日志里表现为一堆重复 SQL

解决方案:

  • 一次性 join 或 IN 批量查询
  • resultMap 做聚合映射(注意去重)
  • 业务层做批量预取

排查手段:

  • 打开 SQL 日志,观察是否出现"同模板 SQL 重复执行 N 次"
  • 用链路追踪看 DB span 数量是否异常

3. 分页:你以为用了分页,其实在内存分页

3.1 正确分页:让 DB 做 limit/offset 或基于游标

  • limit offset, size 简单但 offset 大时会慢
  • 大翻页建议:
    • 基于主键/索引的"seek"方式(where id > lastId limit size)

3.2 常见坑:不小心触发全量查询

  • 没有加 limit
  • PageHelper/拦截器没生效(配置顺序、插件冲突)

排查:

  • 看最终发到 DB 的 SQL 是否有 limit

4. 批处理:减少网络往返,但别把内存打爆

4.1 批处理的收益

  • 单条插入 1000 次 = 1000 次网络往返
  • 批处理 = 1 次或少量往返

4.2 常见误区

  • 一次攒太大批次:
    • MyBatis/JDBC 会缓存参数,容易占用大量内存
  • 没有控制事务:
    • 批处理通常应显式事务,否则每条 auto-commit 性能差

建议:

  • 分批提交(例如 500/1000 一批)
  • 明确事务边界
  • 监控单次批处理耗时与失败重试策略

5. 缓存:一级缓存别神化,二级缓存要谨慎

5.1 一级缓存(SqlSession 级别)

  • 同一个 SqlSession 内重复查询可命中
  • 默认开启

坑:

  • 与事务/会话生命周期强相关
  • 在 Web 应用中通常每次请求一个 SqlSession,收益有限

5.2 二级缓存(Mapper 级别)

  • 跨 SqlSession
  • 需要显式开启,且对象要可序列化

风险:

  • 一致性:更新后缓存失效策略复杂
  • 命中率:命中低反而多一次序列化开销

建议:

  • 更推荐把缓存放到 Redis/本地缓存层,用更可控的失效策略
  • 二级缓存只用于少量稳定读、低写场景

6. 慢 SQL 定位:从 MyBatis 到数据库的闭环

6.1 你需要的三类证据

  • 应用侧:SQL 模板、参数、耗时、调用栈
  • DB 侧:慢日志、执行计划、锁等待
  • 链路侧:某接口中 DB 调用次数与分布

6.2 常见慢因

  • 索引失效(隐式类型转换、函数包裹列、like 前缀 %
  • 返回列过多(select *)
  • 大 offset 分页
  • 锁等待(更新热点行)

6.3 MyBatis 相关的定位点

  • 是否存在大量小 SQL(N+1)
  • 是否事务过大导致锁持有时间长
  • 是否执行了不必要的 flush

7. 参数与映射:性能与正确性的隐形成本

  • 大字段(TEXT/BLOB)不要随意查出来
  • 合理使用延迟加载(谨慎:容易触发 N+1)
  • resultMap 的嵌套映射要注意去重与集合膨胀

8. 面试背诵稿(45 秒)

MyBatis 性能优化我会先分层:优先看 SQL 和索引,再看连接池与 DB 负载,最后才是 MyBatis 使用方式。

最常见的问题是 N+1,我会用 join 或 IN 批量预取解决;分页要确保最终 SQL 带 limit,并且大翻页用基于索引的 seek 分页。

批处理能显著减少网络往返,但要控制批次大小并明确事务边界避免内存膨胀。

缓存方面一级缓存作用受 SqlSession 生命周期限制,二级缓存一致性成本高,通常更建议用独立缓存层。

定位慢 SQL 时要把应用侧 SQL+参数、DB 执行计划和链路调用次数三类证据闭环。

相关推荐
qq_381338502 小时前
Vue3 性能优化实战:从 10s 到 1s 的加载速度提升
性能优化
磊 子2 小时前
Redis详解
linux·数据库·redis·缓存
小陈工3 小时前
Python Web开发入门(三):配置文件管理与环境变量最佳实践
开发语言·jvm·数据库·python·oracle·性能优化·开源
一直都在57216 小时前
Redis(二)
数据库·redis·缓存
PacosonSWJTU19 小时前
(转)mybatis拦截器
数据库·redis·mybatis
Zaki_gd20 小时前
Cortex-M7 D-Cache 与 DMA 缓存一致性说明
java·spring·缓存
keyborad pianist20 小时前
一篇文章学会Redis
数据库·redis·缓存
Mike117.20 小时前
GBase 8c 索引设计与性能优化实战
性能优化
终端鹿20 小时前
Vue3 高频面试题系列:响应式原理 / 组合式 API / 性能优化 3 大核心模块
性能优化