我刚从一场 Java 面试出来,跟面试官聊了快两个小时。他问我:“数据库优化这块,你平时怎么做?”这个问题太经典了,几乎每个 Java 面试都会遇到,但大多数人回答得太空,要么背一堆索引原理,要么甩几个优化工具的名字。面试官想听的是你踩过的坑、总结的套路、能落地的实战技巧。今天我把这些年 Java 面试里数据库优化的必问点、必杀技掰开揉碎地讲给你听,全是干货,不整虚的。

先说说索引优化,这是面试官最爱问的,也是数据库优化最基础的一环。很多人知道索引能加速查询,但不知道什么时候该用、什么时候该避。实战中,我最常遇到的坑是索引失效。比如 WHERE 条件里用了函数,像 ,索引直接失效。正确做法是改成范围查询:。另一个经典场景是联合索引,很多人建了 (a,b,c) 三个字段的联合索引,但查询只用了 b,索引同样失效。记住最左前缀原则:查询条件必须从索引最左边开始。面试时,如果你能说出这些实际场景,面试官立刻会觉得你是个实干派。
接着说 SQL 语句的调优,这是面试里第二高频的问题。很多人上来就甩“用 EXPLAIN 分析”,但 EXPLAIN 只是工具,关键是怎么看结果。我遇到过一个真实案例:一个订单查询接口,用户反馈慢得像在爬,排查后发现 SQL 里有 ,status 字段只有 3 个值,区分度极低,索引根本没用上。解决办法是改成 ,查询速度从 3 秒降到 0.1 秒。面试官想听的就是这种具体怎么发现问题、怎么解决问题的过程,而不是背概念。
再聊聊分页查询优化,这是大流量项目面试的必杀题。很多新手写分页用 ,结果越翻页越慢,因为数据库要扫描前面 10 万行数据。我见过最夸张的例子,一个后台管理系统翻到第 100 页,页面加载了 20 秒。优化思路很简单:用游标分页替代偏移分页。具体做法是记录上一页最后一条记录的 ID,下一页查询 。如果非要保留页码功能,可以先用子查询定位起始 ID:,再用这个 ID 去查 10 条数据。面试时把这种场景讲透,面试官会给你加分。
数据库连接池配置也是个隐藏的雷区,很多 Java 开发者面试时会被问到。我见过一个项目,并发量上来后系统直接宕机,原因是连接池最大连接数设成了 500,数据库扛不住。正确做法是评估业务峰值,比如一个接口耗时 100 毫秒,QPS 是 1000,那理论并发连接数就是 100,设成 150 就够用了。连接池大小不是越大越好,太大反而增加上下文切换开销。还有连接超时时间,生产环境建议设成 30 秒,太短容易误杀长事务,太长又浪费连接资源。面试时能说出这些具体参数和背后的业务逻辑,说明你真有实战经验。
说到事务和锁优化,这是区分初级和高级工程师的分水岭。很多人知道事务隔离级别,但不知道怎么选。我优化过一个库存扣减场景,使用了可重复读隔离级别,结果在高并发下频繁死锁。分析后发现,可重复读的间隙锁导致并发插入时互相等待。优化方案是把隔离级别降到读已提交,同时使用乐观锁:,通过受影响行数判断是否扣减成功。面试官听到这里,肯定会追问“乐观锁怎么处理重试”,你可以顺势说出用 CAS+循环重试,最多 3 次,超过就返回失败,这样的回答会让面试官对你的水平印象深刻。
缓存策略也是数据库优化里绕不开的话题。很多面试者只会说“用 Redis 缓存”,但具体缓存什么、怎么失效、怎么保证一致性,一问就懵。我踩过一个坑:缓存了用户信息,用户修改昵称后,缓存没及时更新,导致用户看到旧昵称。解决方案是采用“先更新数据库,再删除缓存”的策略,配合延迟双删:先删缓存,更新数据库,等几百毫秒再删一次缓存。面试时能说出这种细枝末节,说明你真正做过高并发项目,而不是纸上谈兵。
聊聊慢查询日志和数据归档。很多 Java 面试者会忽略这个点,但它是数据库优化的基本功。生产环境必须开启慢查询日志,阈值设为 1 秒。我每天上班第一件事就是看昨天的慢查询日志,发现一条 SQL 慢了就立刻分析。有一次发现日志里有个查询跑了 5 秒,索引、SQL、数据量都没问题,结果是表数据量已经到了两千万,历史数据拖慢了查询。解决方案是按时间做分区表,每月一个分区,查询时只扫描当月分区。面试时,如果你能说出“我会定期检查慢查询日志,并根据业务特点做数据归档或分区”,面试官会觉得你是个靠谱的工程师。
说了这么多,其实数据库优化没有银弹,核心就八个字:理解业务、对症下药。面试官最看重的不是你知道多少优化技巧,而是你在真实场景下怎么发现问题、分析问题、解决问题。下次面试遇到数据库优化问题,别急着背概念,先问清楚业务场景,然后从索引、SQL、连接池、事务、缓存、慢查询这几个维度逐个剖析。记住,面试官要的不是百科全书,而是一个能帮他修 bug 的人。


