MySQL调优别急着改参数,先把这台机器的账算清楚
接手一台跑得慢的MySQL,很多人的第一反应是打开my.cnf改参数。改完重启,发现还是慢。真正的问题往往不在参数表里,而在你对这台机器在干什么的判断上——它到底是在做点查、在做范围扫描,还是在扛一堆没人优化过的聚合查询。判断错了,参数调得再漂亮也是白搭。
我先说清楚一件事:调优不是把参数往官方推荐值上靠。同一份配置,放在一台只有机械盘的机器上和放在NVMe上,结论能差出一倍。所以下面按「先看瓶颈在哪、再决定花钱方向」的顺序讲。
先看慢查询日志,别看参数表
慢查询日志是唯一不会骗你的东西。long_query_time设成0.5秒还是2秒,取决于你的业务能忍多久。电商详情页超过200毫秒用户就有感知,后台报表跑30秒也没人投诉。
我一般会先把它压到0.5秒跑一天,看日志量。如果一天几十万条,说明阈值太严,业务本身就在做大量全表扫描,这时候先别调参数,先看SQL。
- 用EXPLAIN看type列,出现ALL就是全表扫描,出现index是走索引但扫了整棵索引树。
- 看rows列,估算行数和实际返回行数差一个数量级,说明统计信息过期,ANALYZE TABLE能救。
这两步做完,通常能砍掉一半的慢查询。剩下的才是参数该管的事。
buffer pool给多少,取决于你还有没有别的进程
innodb_buffer_pool_size是MySQL里最值钱的参数,但它的上限不是物理内存,是「物理内存减去其他进程要吃掉的量」。一台64G内存的机器,如果上面只跑MySQL,给到40G到48G都合理;如果还挂着Redis或者PHP-FPM,给32G就得收手。
判断标准很简单:看Innodb_buffer_pool_reads这个状态值。它增长得快,说明缓存没兜住,磁盘在读;它几乎不动,说明给多了,那部分内存是白花的钱。
换我我会先给到物理内存的一半,压测一轮,看命中率能不能稳定在99%以上。上不去就加内存,上去了就别再加,把钱留给磁盘。
磁盘和内存的取舍,是这台机器最贵的一笔账
大多数时候,慢的根因是随机IO。机械盘做点查,一次寻道几毫秒,QPS上不去是物理限制,参数改不动它。
把数据盘换成SSD,同样的SQL延迟能掉一个数量级。这笔钱该不该花,看你的读写比:读多写少的业务,加内存做缓存收益更大;写密集、事务多的业务,SSD几乎是唯一解。
如果预算卡得紧,一台配置扎实的独立服务器比堆参数更实在。比如吉隆坡机房的马来西亚大带宽服务器 VIII,E5-2683v4双路、64G内存、30M带宽,月付$418.50,跑中小型MySQL实例,内存和磁盘都能给到位,不用在参数上抠。
再往上一个量级,比如数据量到了几百G、并发上千,就得看IOPS和带宽一起算。马来西亚大带宽服务器 XX用AMD EPYC 7742双路、256G内存、100M带宽,月付$1408.50,这种配置适合把buffer pool直接开到150G以上,让绝大部分读都落在内存里。贵是贵,但省下的是DBA反复救火的时间。
收尾:先定瓶颈,再定预算
调优的顺序我建议固定成三步:慢查询日志定位SQL,EXPLAIN确认执行计划,状态值确认内存和磁盘谁先撑不住。三步走完,该调参数调参数,该换盘换盘,该升级整机就升级整机。
小站点、读多写少、数据量在几十G以内,先加内存,别急着换机器。数据上百G、写入频繁、延迟要求稳定在10毫秒以内,直接上SSD加高内存的独立服务器,比在原地改参数省事得多。参数是最后一步,不是第一步。