Java开发踩坑:MySQL 慢查询排查全过程
如果你最近也在准备 Java 面试,我整理了一套:
✔ 高频Java面试题(含详细解析)
✔ 模拟真实面试流程训练
✔ 简历优化建议(适合1-5年经验)
已经全部整理成在线版本,方便查阅和练习。
👉 需要的话可以自取:
https://www.myquotego.com

在Java开发中,数据库性能问题是面试和实际项目中都非常重要的技能点。尤其是MySQL慢查询,它可能导致系统响应变慢、用户体验下降,甚至引发系统瓶颈。本篇文章将结合实际开发经验,带你全面掌握MySQL慢查询排查技巧,附带代码示例和优化方案,适合Java面试复习和技术提升。
一、问题背景
在高并发系统中,慢查询是最常见的性能瓶颈之一。慢查询可能源自:
- 不合理的SQL语句
- 索引缺失或使用不当
- 数据量急剧增长
- 不当的连接或子查询
典型场景示例:
SELECT * FROM user WHERE email LIKE '%gmail.com';
在百万级数据表上执行,将非常缓慢,因为LIKE '%xxx’无法走索引。
慢查询不仅影响系统性能,还会引发:
- CPU和IO飙升
- 线程阻塞增加
- 系统响应延迟甚至宕机
我整理了一套完整Java面试题库,
完整版在我的技术站:
https://www.myquotego.com/html/questions?_from=csdn_123_1
二、技术原理解析
1. MySQL慢查询原理
MySQL通过slow_query_log记录执行时间超过long_query_time的SQL语句。慢查询日志本质上是MySQL执行计划和耗时统计的集合。原理如下:
- 查询解析:SQL语句解析生成执行计划
- 执行计划优化:MySQL优化器尝试选择最优索引和Join顺序
- 执行:MySQL逐行扫描或索引查询
- 耗时记录:超过阈值的语句记录到慢查询日志
慢查询原因常见分类:
| 类别 | 原因 |
|---|---|
| SQL设计 | SELECT *、子查询、复杂JOIN |
| 索引问题 | 缺失索引、复合索引顺序错误 |
| 数据量 | 表行数过大、数据倾斜 |
| 系统配置 | innodb_buffer_pool_size过小、缓存未命中 |
2. 排查工具和方法
(1)开启慢查询日志
-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 1; -- 1秒以上记录
(2)使用EXPLAIN分析SQL
EXPLAIN可以查看SQL执行计划,关键字段:
- type:访问类型,优先考虑
ref、const,避免ALL - key:使用的索引
- rows:扫描行数,越小越好
示例:
EXPLAIN SELECT id, name FROM user WHERE email = 'abc@gmail.com';
(3)使用pt-query-digest分析日志
pt-query-digest /var/log/mysql/slow.log
可以统计最耗时的SQL、频率和锁等待情况,帮助定位热点语句。
我整理了一套完整Java面试题库,
完整版在我的技术站:
https://www.myquotego.com/html/questions?_from=csdn_123_1
三、代码示例
1. Java中记录慢查询
使用Spring Boot + MyBatis,可以通过拦截器统计SQL执行时间:
@Intercepts({@Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class SqlTimeInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
long start = System.currentTimeMillis();
Object result = invocation.proceed();
long end = System.currentTimeMillis();
MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
String sqlId = ms.getId();
long time = end - start;
if(time > 1000) { // 超过1秒记录慢查询
System.out.println("慢查询 SQL: " + sqlId + " 耗时: " + time + "ms");
}
return result;
}
}
2. 优化SQL示例
原SQL:
SELECT * FROM order WHERE customer_id = 123 ORDER BY created_at DESC;
优化方式:
- 添加索引:
customer_id + created_at - 只查询需要字段:
CREATE INDEX idx_customer_created ON order(customer_id, created_at);
SELECT id, total_amount FROM order
WHERE customer_id = 123
ORDER BY created_at DESC;
优化后,扫描行数大幅下降,响应时间显著提升。
四、实际应用场景
1. 高并发系统
在电商秒杀、红包系统中,如果慢查询未优化:
- 页面加载延迟
- 订单处理积压
- 数据库连接池耗尽
优化方案:
- 合理设计索引
- 避免
SELECT * - 分库分表、读写分离
- 使用缓存(Redis/Memory)减少数据库压力
2. 大数据分析
对于日志、统计分析等场景:
- 使用分区表、分表策略
- 避免全表扫描
- 结合
EXPLAIN调整索引
3. 面试考点
Java面试中,慢查询常考点:
EXPLAIN分析结果解读- 索引设计原则
- SQL优化策略
- Java端如何记录和监控慢查询
我整理了一套完整Java面试题库,
完整版在我的技术站:
https://www.myquotego.com/html/questions?_from=csdn_123_1
五、总结
MySQL慢查询排查是一项系统工程,涉及SQL设计、索引优化、执行计划分析和Java端监控。在日常开发中应:
- 及时开启慢查询日志
- 使用
EXPLAIN分析SQL - 合理设计索引
- 避免全表扫描和不必要的子查询
- 在Java端监控慢查询,结合日志分析热点SQL
通过本文方法,你可以:
- 快速定位慢查询
- 提高数据库性能
- 在面试中展示实际优化能力
关注我,持续更新Java面试核心知识。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)