如果你最近也在准备 Java 面试,我整理了一套:

✔ 高频Java面试题(含详细解析)
✔ 模拟真实面试流程训练
✔ 简历优化建议(适合1-5年经验)

已经全部整理成在线版本,方便查阅和练习。

👉 需要的话可以自取:

https://www.myquotego.com


在Java面试中,关于MySQL性能优化的问题非常常见,尤其是“慢查询”的排查与优化。面试官往往希望你不仅知道慢查询的概念,还能分析原因、给出解决方案,并结合实际代码实践。本文将以实际案例和技术原理为基础,深入讲解MySQL慢查询排查的全过程。

[外链图片转存中…(img-CnzZy2pc-1773664820848)]

我整理了一套完整Java面试题库,
完整版在我的技术站:
https://www.myquotego.com/html/questions?_from=csdn_123_1


1. 问题背景

在高并发系统中,数据库性能是核心瓶颈之一。慢查询是影响MySQL性能的常见因素,表现为单条SQL执行时间过长,导致系统响应慢、服务堆积甚至宕机。

常见原因包括:

  • 数据量过大,导致全表扫描
  • 索引使用不合理或缺失
  • SQL语句本身写法不高效
  • 数据库配置不合理(如缓冲区、查询缓存)
  • 高并发下锁竞争

面试官通常会问:

  • 如何判断SQL是否慢?
  • 如何定位慢查询?
  • 如何优化慢查询?
  • 请给出具体实践案例

2. 技术原理解析

2.1 什么是慢查询

MySQL中的慢查询指执行时间超过设定阈值的SQL语句。默认阈值为10秒,但在生产中通常设置为1秒甚至更低:

show variables like 'long_query_time';
set global long_query_time = 1;

MySQL会将慢查询记录在slow_query_log日志中,通过日志分析可定位问题SQL。

2.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. 分析执行计划(EXPLAIN)

通过EXPLAIN查看SQL执行计划,重点关注:

  • type:访问类型,理想是refconst,避免ALL
  • rows:扫描行数,数字越大说明消耗越多
  • Extra:是否使用了Using temporaryUsing filesort

示例:

EXPLAIN SELECT * FROM orders WHERE user_id = 123;
  1. 索引优化
  • 建立合适的单列索引或组合索引
  • 避免在索引列上进行函数操作或类型转换
  • 删除冗余索引
  1. SQL优化
  • 使用JOIN替代子查询
  • 避免SELECT *,只查询必要字段
  • 分页查询使用LIMIT offset, size优化
  1. 数据库配置优化
  • 调整innodb_buffer_pool_size,保证热点数据在内存中
  • 调整query_cache_size(MySQL 5.7以前)
  • 配置连接池和并发参数

3. 代码示例

假设我们有一个订单表orders,包含百万级数据,查询用户订单信息:

CREATE TABLE orders (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    status VARCHAR(20),
    total_amount DECIMAL(10,2),
    created_at DATETIME,
    INDEX idx_user_created(user_id, created_at)
);

3.1 慢查询示例

SELECT * FROM orders WHERE user_id = 123 ORDER BY created_at DESC;

如果没有索引,MySQL会进行全表扫描,执行时间长。

3.2 优化后的SQL

-- 使用联合索引优化
SELECT id, status, total_amount 
FROM orders 
WHERE user_id = 123 
ORDER BY created_at DESC 
LIMIT 20;

通过EXPLAIN查看:

+----+-------------+--------+-------+-----------------+----------------+---------+------+-------+--------------------------+
| id | select_type | table  | type  | possible_keys   | key            | key_len | ref  | rows  | Extra                    |
+----+-------------+--------+-------+-----------------+----------------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | orders | ref   | idx_user_created| idx_user_created| 12      | const|    20 | Using index; Using filesort|
+----+-------------+--------+-------+-----------------+----------------+---------+------+-------+--------------------------+

此时SQL走了索引,扫描行数少,避免了全表扫描。

3.3 Java调用示例

在Spring Boot中使用JPA或MyBatis:

// MyBatis Mapper
@Select("SELECT id, status, total_amount FROM orders WHERE user_id = #{userId} ORDER BY created_at DESC LIMIT #{limit}")
List<Order> findUserOrders(@Param("userId") Long userId, @Param("limit") int limit);

通过分页+索引,显著提升查询性能。

我整理了一套完整Java面试题库,
完整版在我的技术站:
https://www.myquotego.com/html/questions?_from=csdn_123_1


4. 实际应用场景

  1. 电商系统订单查询

高并发下,用户订单查询需要秒级响应,通过慢查询日志排查并优化SQL和索引,可以降低数据库负载。

  1. 日志分析系统

日志数据量大,通过分表、索引和分页查询,避免全表扫描。

  1. 统计报表

报表SQL复杂,容易产生慢查询,通过EXPLAIN分析和拆分SQL,实现高效查询。


5. 总结

慢查询是数据库性能瓶颈的核心因素之一。排查慢查询的关键步骤:

  1. 开启慢查询日志,定位问题SQL
  2. 使用EXPLAIN分析执行计划,检查索引使用情况
  3. 对SQL进行优化,减少扫描行数
  4. 调整数据库配置,提升性能
  5. 实践中结合分页查询、索引优化和合理的SQL写法

[外链图片转存中…(img-e1R3ejAH-1773664820849)]

通过上述方法,Java开发者不仅能在面试中给出完整答案,也能在实际项目中显著提升MySQL查询性能。

我整理了一套完整Java面试题库,
完整版在我的技术站:
https://www.myquotego.com/html/questions?_from=csdn_123_1

关注我,持续更新Java面试核心知识。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐