先看慢查询日志,别急着调参数
MySQL性能调优的第一步不是改
innodb_buffer_pool_size,也不是加索引,而是确认“到底哪些SQL在拖慢系统”。很多团队一上来就调大缓冲池、换SSD、升级CPU,结果发现90%的延迟来自一条没走索引的
SELECT *全表扫描。
实操建议:
用show variables like 'slow_query_log';确认是否开启;没开就执行
set global slow_query_log = 1;把
long_query_time设为1秒(
set global long_query_time = 1;),比默认10秒更早暴露问题 日志输出建议设为
FILE(
set global log_output = 'FILE';),避免写入
mysql.slow_log表带来额外开销 用
mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log快速找出耗时TOP10的SQL
用EXPLAIN看执行计划,而不是猜索引有没有用
看到慢SQL后,别直接建索引。先跑一遍
EXPLAIN,否则极容易建错索引——比如给
WHERE a = ? AND b IN (?, ?) ORDER BY c建了
(a)单列索引,实际需要的是
(a, b, c)联合索引。
重点关注三项:
type:从
ALL(全表扫描)→
range→
ref→
const是优化方向;如果还是
ALL,说明没走索引或索引失效
rows:预估扫描行数,和实际数据量差距过大(比如表有10万行,
rows=98234),大概率没利用好索引选择性
Extra里出现
Using filesort或
Using temporary,意味着排序/分组没走索引,必须干预
调innodb_buffer_pool_size
前,先验证内存是否真够用
盲目把
innodb_buffer_pool_size设成物理内存70%,可能反而引发OS频繁swap——尤其当服务器还跑着Java应用或Redis时。真正该看的是InnoDB缓冲池的“水位”是否健康。
执行
SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool_pages_%';后关注两个数字:
Innodb_buffer_pool_pages_free≈ 0?说明缓冲池长期打满,但不等于“足够大”——得结合
Innodb_buffer_pool_reads(磁盘读次数)判断:如果该值持续 > 100/秒,说明频繁回磁盘,才真需要扩容
Innodb_buffer_pool_read_requests÷
Innodb_buffer_pool_reads注意:重启MySQL后
pages_free会重置,要等业务流量稳定后再观察
转换MyISAM表到InnoDB时,小心ALTER TABLE ... ENGINE=InnoDB
锁表
线上大表执行
ALTER TABLE t ENGINE=InnoDB会全程锁表(尤其MySQL 5.6及之前),业务高峰期执行等于主动停服。这不是“要不要转”的问题,而是“怎么转才不伤业务”。
安全做法:
对500MB以上表,优先用pt-online-schema-change(Percona Toolkit),它通过触发器+影子表实现无锁变更 若只能用原生命令,务必在低峰期执行,并提前用
SELECT COUNT(*)确认表大小;千万避开
mysqldump + DROP + IMPORT这种“先清空再重建”的方式——期间数据完全不可用 转换后检查
innodb_file_per_table=1是否生效,否则所有表数据仍挤在
ibdata1里,后续无法单独收缩某张表空间
真正的调优起点从来不在配置文件里,而在每条被
EXPLAIN戳穿的SQL和每份被
mysqldumpslow揪出的慢日志中。最容易被忽略的,其实是“没查慢日志就调参”和“没看
rows就建索引”这两件事。
