MySQL 数据库优化是一个系统性工程,涉及多个层面(SQL、索引、配置、架构等)。以下是一套较为全面的 MySQL 优化方案,适用于大多数中大型应用:
一、SQL 层面优化
1. 避免 SELECT *
- 只查询需要的字段,减少网络传输和内存占用。
2. 使用 EXPLAIN 分析执行计划
- 查看是否使用了索引、是否有全表扫描(type=ALL)、是否出现临时表或文件排序等。
EXPLAIN SELECT * FROM users WHERE age > 30;
3. 避免在 WHERE 子句中对字段进行函数操作或表达式计算
- 会导致索引失效:
-- 不推荐
SELECT * FROM orders WHERE YEAR(create_time) = 2024;
-- 推荐
SELECT * FROM orders WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01';
4. 合理使用 JOIN
- 尽量减少多表 JOIN,尤其是大表之间的 JOIN。
- 确保 JOIN 字段上有索引。
5. 避免使用 OR(可改写为 UNION)
- OR 可能导致索引失效(除非所有条件字段都有索引)。
6. 使用 LIMIT 限制结果集
- 特别是分页查询时,避免 OFFSET 过大(可考虑基于游标的分页)。
二、索引优化
1. 为高频查询字段添加索引
- WHERE、ORDER BY、GROUP BY、JOIN 的字段优先考虑。
2. 使用复合索引(联合索引)
- 遵循最左前缀原则。
- 例如:
(status, create_time)可用于WHERE status = 1 ORDER BY create_time。
3. 避免冗余和重复索引
- 定期使用工具(如
pt-duplicate-key-checker)检查。
4. 谨慎使用全文索引、前缀索引
- 全文索引适用于文本搜索;前缀索引适用于长字符串(如 VARCHAR(255)),但要注意选择性。
5. 监控索引使用情况
- 通过
information_schema.STATISTICS或慢查询日志分析未使用的索引。
三、数据库结构设计优化
1. 合理选择数据类型
- 使用最小够用的数据类型(如 TINYINT 代替 INT 存布尔值)。
- 时间字段优先使用
DATETIME或TIMESTAMP,避免字符串存储。
2. 规范化与反规范化权衡
- OLTP 系统倾向规范化;OLAP 或高并发读场景可适当反规范化以减少 JOIN。
3. 分库分表(Sharding)
- 单表超过千万级记录时考虑水平拆分。
- 可按用户 ID、时间等维度拆分。
4. 冷热数据分离
- 历史数据归档到历史表或数据仓库,提升主表性能。
四、MySQL 配置优化(my.cnf)
1. InnoDB 相关参数
innodb_buffer_pool_size = 总内存的 50%~70%(专用数据库服务器)
innodb_log_file_size = 1~2G(提高写性能)
innodb_flush_log_at_trx_commit = 1(安全)或 2(性能,容忍少量丢失)
innodb_io_capacity = 根据 SSD IOPS 设置(如 2000+)
2. 查询缓存(MySQL 8.0 已移除)
- 5.7 及以下版本:若查询重复率高可开启,否则建议关闭(
query_cache_type=0)。
3. 连接数与线程池
max_connections = 根据业务需求(通常 200~1000)
thread_cache_size = 适当调高(如 50)
4. 临时表与排序
tmp_table_size = 64M
max_heap_table_size = 64M
五、运维与监控
1. 开启慢查询日志
slow_query_log = 1
long_query_time = 1 # 超过1秒记录
log_queries_not_using_indexes = 1(可选)
2. 使用性能分析工具
SHOW PROCESSLIST:查看当前运行 SQL。Performance Schema/sys schema:深入分析性能瓶颈。pt-query-digest(Percona Toolkit):分析慢日志。
3. 定期维护
OPTIMIZE TABLE(仅适用于 MyISAM 或碎片严重的 InnoDB 表)。- 更新表统计信息:
ANALYZE TABLE。
六、架构层面优化
1. 读写分离
- 主库写,从库读(通过中间件如 MyCAT、ShardingSphere 或应用层实现)。
2. 缓存层引入
- Redis / Memcached 缓存热点数据,减轻数据库压力。
3. 异步处理
- 非关键写操作(如日志、通知)通过消息队列异步写入。
七、升级与版本选择
- 优先使用 MySQL 8.0(性能更好、支持 CTE、窗口函数、隐藏索引等)。
- 避免使用已停止维护的版本(如 5.5 以下)。
总结
| 优化层级 | 关键措施 |
|---|---|
| SQL | EXPLAIN、避免函数操作、LIMIT、合理 JOIN |
| 索引 | 覆盖索引、联合索引、避免冗余 |
| 结构 | 合理字段类型、分表分库、冷热分离 |
| 配置 | buffer pool、日志大小、连接数 |
| 架构 | 读写分离、缓存、异步队列 |
💡 建议流程:先通过慢查询日志定位问题 SQL → 用 EXPLAIN 分析 → 优化索引或重写 SQL → 若仍不足,再考虑配置或架构调整。
如需针对具体场景(如高并发写、大数据量报表等)进一步优化,可提供详细业务背景。
1180

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



