2026年7月11日 · 6 分钟阅读
MySQL 性能优化实战:连接池、Explain、慢查询、索引优化与配置调优
基于数据库进阶课程笔记,梳理 MySQL 调优目标、数据库压测、连接池参数、Explain 执行计划、索引优化、LIMIT 和子查询优化、Profile、慢查询日志、连接数、表结构和配置优化。
MySQL 性能优化不是只会写 EXPLAIN,也不是看见慢 SQL 就加索引。一次有效的数据库调优,应该从目标、压测、执行计划、慢查询、索引、连接池和配置多个层面一起看。
数据库通常是后端系统里最容易成为瓶颈的一环,因为它同时承担数据存储、查询、事务、锁和连接管理。
为什么要做数据库调优
数据库性能会直接影响用户体验。
常见问题包括:
- 慢查询导致页面加载慢。
- 数据库连接超时导致 5xx。
- 锁等待导致数据无法提交。
- 大事务拖慢系统。
- 连接数打满导致请求堆积。
调优的目标不是让某条 SQL 在本机跑得更快,而是让系统整体吞吐、稳定性和响应时间更好。
什么影响数据库性能
影响 MySQL 性能的因素很多:
| 层面 | 影响因素 |
|---|---|
| 服务器 | CPU、内存、磁盘 IO、网络 |
| 表结构 | 字段设计、范式、冗余、冷热拆分 |
| SQL | 查询写法、join、子查询、排序、分页 |
| 索引 | 是否命中、是否覆盖、是否失效 |
| 事务 | 大事务、锁等待、隔离级别 |
| 配置 | 连接数、缓冲区、日志刷盘策略 |
| 架构 | 主从、读写分离、分库分表 |
| 客户端 | 连接池大小、超时时间、连接属性 |
所以调优要先定位瓶颈,而不是直接改参数。
数据库压测
数据库也可以用 JMeter 做压测。
常见步骤:
- 添加 JDBC 驱动。
- 配置 JDBC Connection Configuration。
- 设置连接池变量名。
- 配置数据库 URL、用户名、密码。
- 添加 JDBC Request。
- 填写 SQL、参数和超时时间。
- 运行压测并观察响应时间、错误率和吞吐量。
压测要注意连接池配置。如果客户端连接池先耗尽,看到的就不是数据库真实性能。
连接池参数
连接池不是越大越好。
常见参数:
| 参数 | 含义 |
|---|---|
| MaxActive | 最大活跃连接数 |
| MaxWait | 获取连接最大等待时间 |
| ConnectionTimeout | 建立连接超时时间 |
| MinIdle | 最小空闲连接数 |
| MaxIdle | 最大空闲连接数 |
最大连接数过小,请求会排队;最大连接数过大,数据库线程和资源压力会升高,反而可能降低性能。
连接池调优的核心是:让应用并发能力和数据库承载能力匹配。
Explain 是什么
EXPLAIN 可以查看 MySQL 对一条 SELECT 语句生成的执行计划。
用法:
explain select * from user where id = 1;
它不会真正返回业务结果,而是告诉你优化器准备怎么执行这条 SQL。
重点看:
select_typetypekeyrowsExtra
type 字段
type 表示访问类型,是判断 SQL 好坏的重要字段。
常见顺序大致可以理解为:
system > const > eq_ref > ref > range > index > ALL
| type | 说明 |
|---|---|
| const | 主键或唯一索引等值查询,最多一行 |
| eq_ref | join 中唯一索引匹配 |
| ref | 非唯一索引等值查询 |
| range | 范围索引扫描 |
| index | 全索引扫描 |
| ALL | 全表扫描 |
看到 ALL 时要重点关注是否缺索引、索引失效或数据量太小导致优化器认为全表扫描更便宜。
Extra 字段
Extra 会提示额外执行信息。
常见值:
| Extra | 含义 |
|---|---|
| Using index | 使用覆盖索引 |
| Using where | Server 层还要过滤 |
| Using temporary | 使用临时表 |
| Using filesort | 额外排序 |
| Using index condition | 使用索引条件下推 |
Using temporary 和 Using filesort 经常是优化重点,但也要结合数据量和业务场景看。
索引优化原则
适合建索引:
- 高频 where 条件。
- order by / group by 字段。
- join 关联字段。
- 可以形成覆盖索引的查询字段。
不适合建索引:
- 表数据很少。
- 区分度低。
- 更新频繁。
- 字段过长。
- 无序值,如 UUID。
联合索引优先级通常高于多个单列索引,因为它可以同时服务过滤、排序和覆盖索引。
常见 SQL 优化
一些常见优化方向:
- 避免
select *,只查需要字段。 - 避免在索引列上使用函数或计算。
- 字符串字段查询记得加引号。
- 避免大偏移量
limit。 - 子查询能改 join 时结合执行计划判断。
- 大事务拆小。
- 批量操作控制单批大小。
优化 SQL 时,不要只看语法,要看执行计划和实际扫描行数。
LIMIT 优化
大分页常见问题:
select * from user order by id limit 100000, 20;
MySQL 需要跳过大量记录,成本很高。
优化思路:
- 使用主键游标分页。
- 先查主键,再回表。
- 限制最大可翻页深度。
- 借助搜索引擎处理复杂检索。
例如:
select * from user where id > 100000 order by id limit 20;
这种方式更适合连续翻页场景。
慢查询日志
数据库性能问题里,很多来自慢 SQL。慢查询日志可以记录执行时间超过阈值的 SQL。
常见配置:
set global slow_query_log = on;
set global long_query_time = 1;
慢查询日志能帮助定位:
- 哪些 SQL 慢。
- 慢 SQL 执行频率。
- 扫描行数。
- 是否使用索引。
- 是否存在锁等待。
线上分析慢查询时,可以结合 mysqldumpslow 或 pt-query-digest。
Profile
Profile 可以分析 SQL 在各阶段耗时。
大致流程:
set profiling = 1;
select ...;
show profiles;
show profile for query 1;
它适合学习和定位单条 SQL 各阶段耗时,但生产环境更常依赖慢查询日志、监控和 Performance Schema。
数据库结构优化
结构优化方向包括:
- 字段很多的表拆分成多个表。
- 增加中间表减少复杂 join。
- 适当增加冗余字段减少查询成本。
- 冷热数据分离。
- 大表归档。
结构优化往往比 SQL 小修小补收益更大,但也要考虑一致性和维护成本。
配置和硬件优化
配置层面常见优化:
max_connections:最大连接数。- Buffer Pool 大小。
- 慢查询阈值。
- binlog 格式。
- redo log 刷盘策略。
- 临时表大小。
硬件层面:
- 更高性能 SSD。
- 更多内存。
- 更稳定网络。
- 更强 CPU。
但硬件扩容不是调优的替代品。低效 SQL 和糟糕索引会吞掉再多硬件。
小结
MySQL 性能优化可以按这个顺序做:
- 先用监控和慢查询定位问题。
- 用 Explain 看执行计划。
- 优化 SQL 和索引。
- 检查连接池和事务范围。
- 再考虑表结构、配置、硬件和架构。
- 每次优化后压测或观察指标验证。
数据库调优最怕凭感觉。好的优化一定能说清楚:慢在哪里、为什么慢、改了什么、指标如何变化。