目标你能把 MyBatis 的性能问题拆成“SQL 本身 JDBC/网络 MyBatis 使用方式”三层并掌握可落地的优化点。1. 性能问题先分层不要一上来就调 MyBatisMyBatis 慢常见根因优先级通常是SQL/索引设计占大头连接池/网络/DB 负载MyBatis 使用方式N1、错误分页、批处理不当面试时你要体现“先定位再优化”的工程能力。2. N1 问题最常见的 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 size3.2 常见坑不小心触发全量查询没有加 limitPageHelper/拦截器没生效配置顺序、插件冲突排查看最终发到 DB 的 SQL 是否有 limit4. 批处理减少网络往返但别把内存打爆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 相关的定位点是否存在大量小 SQLN1是否事务过大导致锁持有时间长是否执行了不必要的 flush7. 参数与映射性能与正确性的隐形成本大字段TEXT/BLOB不要随意查出来合理使用延迟加载谨慎容易触发 N1resultMap 的嵌套映射要注意去重与集合膨胀8. 面试背诵稿45 秒MyBatis 性能优化我会先分层优先看 SQL 和索引再看连接池与 DB 负载最后才是 MyBatis 使用方式。最常见的问题是 N1我会用 join 或 IN 批量预取解决分页要确保最终 SQL 带 limit并且大翻页用基于索引的 seek 分页。批处理能显著减少网络往返但要控制批次大小并明确事务边界避免内存膨胀。缓存方面一级缓存作用受 SqlSession 生命周期限制二级缓存一致性成本高通常更建议用独立缓存层。定位慢 SQL 时要把应用侧 SQL参数、DB 执行计划和链路调用次数三类证据闭环。