MySQL 性能优化指南,涵盖开发、SQL、索引、架构、运维等所有层面
🚀 一、MySQL 性能优化总体思路(非常关键)
MySQL 性能问题本质来自 4 个方面:
层级 优化方向
SQL 层 SQL 写法、使用索引情况
表结构 字段类型、索引设计、分表、范式程度
MySQL 服务层 buffer pool、连接数、慢查询
架构层 主从、读写分离、分库分表、缓存
⭐ 二、最有效的 SQL 优化(80% 的性能问题来自这里)
- 永远优先使用索引字段做查询条件
WHERE name = ‘xxx’
WHERE id IN (…)
WHERE create_time BETWEEN …
不要对索引字段做函数操作:
❌
WHERE DATE(create_time) = ‘2024-01-01’
改成 ✔
WHERE create_time >= ‘2024-01-01 00:00:00’
AND create_time < ‘2024-01-02 00:00:00’
- 只查你需要的字段(避免 SELECT *)
SELECT * 会:
扫描所有字段
不能使用覆盖索引
增加网络传输
增加 buffer pool 压力
- 限制分页深度(大分页非常慢)
大分页如:
LIMIT 1000000, 20
MySQL 会扫描前 100w 行丢弃。
解决方案:
WHERE id > ?
LIMIT 20
或使用覆盖索引 + 子查询。
- WHERE + ORDER BY 涉及不同字段 → 必须使用联合索引
例如:
WHERE status = 1
ORDER BY create_time DESC
最好建立复合索引:
(status, create_time)
- 避免使用 OR(特别慢)
❌
WHERE name = ‘xxx’ OR phone = ‘xxx’
改为 ✔ 分两次查或 UNION ALL。
- 尽量避免 LIKE ‘%xxx%’
%xxx% 无法走索引,必须改成:
使用全文索引(FullText)
使用前缀匹配 LIKE ‘xxx%’
- COUNT(*) 很慢?其实 InnoDB 里就是慢
如果经常查总数,可以:
Redis 缓存计数
消息队列计数
维护单独的统计表
⭐ 三、索引设计(性能的核心)
- 索引数量并不是越多越好
每行 INSERT / UPDATE 都需要同步所有相关索引。
一般表的索引数量:5 个以内最合理。
- 联合索引前缀法则(非常重要)
一个组合索引 (a, b, c) 会生效于:
a
a, b
a, b, c
不会用于:
b alone
c alone
b, c together
- 索引字段尽量选“区分度高”的字段
比如 gender(男女)区分度太低,不适合作索引字段。
- 使用覆盖索引让查询完全不读表
例子:
SELECT id, name FROM user WHERE age = 18;
如果索引是 (age, id, name)
→ 查询只走索引,不访问表数据,速度会快几十倍。
⭐ 四、表结构优化
- 字段类型要最小可行
越长越耗空间、越慢:
建议 原因
使用 TINYINT/SMALLINT 代替 INT 节省空间(缓存命中率提升)
使用 VARCHAR(20) 不要 VARCHAR(255) 减少内存、磁盘扫描
使用 DATETIME,不要使用 VARCHAR 存日期 可排序、可索引
2. 避免 TEXT / BLOB(非常慢)
把大字段放到独立表,用 ID 关联。
- 非必要不要使用外键(业务系统中)
外键会导致:
更新阻塞
删除阻塞
索引额外开销
建议应用层做校验。
⭐ 五、MySQL 服务层优化
- 必配参数:innodb_buffer_pool_size
推荐设置为 可用内存的 50% ~ 70% 。
这是 MySQL 性能天花板的核心。
- 开启慢查询日志
分析哪些 SQL 慢:
slow_query_log = 1
long_query_time = 1
用 pt-query-digest 分析慢查询非常强大。
- 合理的连接池参数(你在 Spring 中常用)
maxActive = 100~300
minIdle = 20
⭐ 六、架构层性能优化(吞吐量爆发用)
当数据库压力大到瓶颈,可以做以下事情:
- 主从复制 + 读写分离
解决读多写少的压力。
- Redis 缓存(命中率高时性能 ×100)
适宜缓存:
热点数据
列表
统计
大查询结果
- 分库分表
分两类:
垂直分库(按业务)
水平分表(按 user_id / hash(字段))
适合千万级、亿级数据。
- ElasticSearch / ClickHouse 进行搜索或分析
MySQL 不是搜索引擎,也不是数仓。
⭐ 七、你可以用的简单性能测试工具
EXPLAIN
SHOW PROFILE
pt-query-digest(最强)
Navicat / DataGrip 的可视化分析
1696

被折叠的 条评论
为什么被折叠?



