MySQL 调优

一、调优总原则(最重要)

  1. 80% 性能问题来自慢 SQL + 索引缺失
  2. 调优顺序:SQL 语句 → 索引 → 表结构 → 配置参数 → 架构
  3. 不要盲目改配置,先监控、再定位、最后优化

二、SQL 语句优化(最见效)

1. 定位慢查询

开启慢查询日志,捕获执行慢的 SQL:

复制代码
slow_query_log = 1
long_query_time = 1  # 超过1秒记录
slow_query_log_file = /var/log/mysql/slow.log
log_queries_not_using_indexes = 1  # 记录未使用索引的SQL

常用分析工具:

  • mysqldumpslow
  • pt-query-digest(Percona 工具)

2. 必须会用:EXPLAIN 执行计划

通过 EXPLAIN 查看 SQL 是否走索引、扫描行数、是否全表扫描。

重点关注字段:

  • type :最优到最差 system > const > eq_ref > ref > range > index > ALL
    • 出现 ALL = 全表扫描,必须优化
  • key:实际使用的索引,为 NULL 说明没走索引
  • rows:扫描行数,越小越好
  • Extra :出现 Using filesort / Using temporary 必须优化

3. 常见 SQL 优化规则

  1. 禁止 SELECT *,只查需要的字段

  2. 避免在索引列上运算 / 函数

    复制代码
    错误:WHERE DATE(create_time) = '2025-01-01'
    正确:WHERE create_time >= '2025-01-01' AND create_time < '2025-01-02'
  3. 避免 != / <> / IS NULL / OR 导致索引失效

  4. 模糊查询 %xxx 无法使用索引

  5. JOIN 关联字段必须建立索引,且类型一致

  6. 少用子查询,推荐用 JOIN 代替

  7. 分页深度优化

    复制代码
    错误:SELECT * FROM t LIMIT 1000000,10
    正确:SELECT * FROM t WHERE id>1000000 LIMIT 10

三、索引优化(核心)

1. 索引设计原则

  • 最左前缀原则:联合索引 (a,b,c),查询必须包含 a 才能命中索引
  • 区分度高的字段放前面
  • 单张表索引不超过 5 个
  • 联合索引不超过 3 个字段
  • 频繁更新的字段不建索引
  • 小表不建索引(全表扫描更快)

2. 必须建索引的场景

  • WHERE 条件频繁使用的字段
  • JOIN 关联字段
  • ORDER BY / GROUP BY 字段
  • 覆盖索引(查询字段全部在索引中,无需回表)

3. 索引失效场景(高频)

  • 索引列使用函数、运算、类型转换
  • % 开头的模糊查询
  • OR 连接的条件有一个字段无索引
  • 使用 NOT IN / != / <> / IS NOT NULL
  • 联合索引不满足最左前缀

4. 索引最佳实践

复制代码
-- 建立联合索引(最左前缀)
CREATE INDEX idx_user_status_create ON user(status, create_time);

-- 覆盖索引(避免回表)
CREATE INDEX idx_order_user_no ON order(user_id) INCLUDE (order_no, amount);

四、表结构优化

1. 字段类型选择(越小越好)

  • 能用 TINYINT 不用 INT
  • 能用 INT 不用 BIGINT
  • 时间用 DATETIME 不用字符串
  • 字符串长度固定用 CHAR,可变用 VARCHAR
  • 禁止使用 TEXT/BLOB 做查询条件

2. 设计规范

  • 必须有主键(推荐自增 ID/BIGINT)
  • 所有字段设置 NOT NULL,用默认值代替 NULL
  • 大字段拆分到副表
  • 禁止频繁 ALTER TABLE

3. 分表分库(大数据量必备)

  • 单表超过 1000 万 考虑分表
  • 水平分表:按时间、用户 ID 哈希
  • 垂直分表:冷热字段分离

五、MySQL 配置优化(my.cnf)

1. 内存配置(最关键)

根据服务器内存调整:

8G 内存推荐配置
复制代码
[mysqld]
# 连接数
max_connections = 1000
back_log = 512

# 缓冲池(最重要!)
innodb_buffer_pool_size = 6G  # 设为物理内存的 50%~70%

# 日志
innodb_log_file_size = 2G
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 1  # 安全模式
sync_binlog = 1

# 临时表
tmp_table_size = 256M
max_heap_table_size = 256M

# 排序&连接
sort_buffer_size = 2M
join_buffer_size = 2M
read_buffer_size = 2M

# 其他
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT

2. 核心参数说明

  • innodb_buffer_pool_size:InnoDB 缓存,越大性能越好
  • max_connections:最大连接数
  • innodb_flush_log_at_trx_commit:1 = 最安全,2 = 高性能
  • innodb_file_per_table:每个表独立表空间,推荐开启

六、架构层面优化

1. 读写分离

  • 主库写,从库读
  • 工具:MyCat、Sharding-JDBC、MySQL Router

2. 缓存

  • 热点数据放 Redis,避免频繁查库
  • 页面缓存、接口缓存

3. 防止数据库雪崩

  • 限流
  • 熔断
  • 降级
  • 超时控制

七、操作系统层面优化

  1. 关闭 swap
  2. 文件系统用 ext4/xfs
  3. IO 调度:noop /deadline
  4. 打开文件数限制调高
  5. 关闭数据库所在磁盘的 atime

八、日常监控与维护

1. 必看状态

复制代码
SHOW ENGINE INNODB STATUS;
SHOW PROCESSLIST;
SHOW VARIABLES LIKE '%buffer_pool%';
SHOW STATUS LIKE '%Threads%';

2. 定期维护

  • 定期分析表 ANALYZE TABLE
  • 优化表 OPTIMIZE TABLE(碎片整理)
  • 定期删除冗余索引
  • 慢查询持续监控
相关推荐
m晴朗2 天前
ffmpeg(2)-音频相关知识
ffmpeg·音视频
山栀shanzhi2 天前
【FFmpeg实战】手撕音频转码:WAV转AAC的全链路解析与C++实现
ffmpeg·音视频·aac
深念Y3 天前
FFmpeg 480p 转码失败但 1080p/720p 正常的坑
ffmpeg·音视频·转码·流媒体·分辨率·hls·m3u8
七点半7703 天前
FFmpeg C++ AI视觉开发核心手册 (整合版)适用场景:视频流接入、AI模型预处理(抽帧/缩放/格式转换)、高性能算法集成。
c++·人工智能·ffmpeg
hu55667985 天前
FFmpeg 如何合并字幕
ffmpeg
屋檐上的大修勾5 天前
使用ffmpeg本地发布rtmp/rtsp直播流
ffmpeg
紫金修道5 天前
【编解码】基于CPU的高性能 RTSP 多路摄像头抓帧插件:设计与实现详解
ffmpeg
雄哥0075 天前
Windows系统下FFmpeg的安装与环境配置指南
windows·ffmpeg
ALONE_WORK5 天前
ffmpeg-rk3568-mpp 硬件加速版本
ffmpeg·视频编解码·mpp·视频推流