MySQL调优先看这三步,慢查询日志别急着关

2026-09-28 23:25 1002 次浏览

调优之前,先搞清楚瓶颈在哪一层

数据库跑得慢,很多人第一反应是改参数。改完发现没动静,又开始怀疑SQL写得烂。其实调优最怕的就是跳步——还没定位瓶颈,就开始东改西改,最后连哪个改动生效了都不知道。

我一般会把调优分成三层来看。最底下是硬件层,磁盘能扛多少IOPS、内存够不够装下热数据、CPU核数能不能撑住并发。中间是配置层,innodb_buffer_pool_size给多大、连接数上限设多少。最上面才是SQL层,索引走没走对、执行计划是不是全表扫描。三层里越往下改,见效越明显,但代价也越大。换我我会先看慢查询日志,把最耗时的几条SQL捞出来,再判断问题出在哪一层。

慢查询日志的配置不复杂,把long_query_time设成0.5秒或者1秒,跑上一天,基本上热点就出来了。这一步花不了多少时间,但能省掉后面很多瞎猜。

硬件层:磁盘和内存决定调优天花板

MySQL对磁盘的敏感程度,比很多人想象的要高。机械硬盘随机读写大概只有100到200 IOPS,而一块像样的NVMe SSD轻松跑到几十万IOPS。这个差距不是靠改参数能追回来的。

我见过不少配置,CPU和内存都堆得很高,结果磁盘还是SATA SSD甚至机械盘,数据库一有写入高峰就卡住。这种情况你调innodb_flush_log_at_trx_commit也好,调innodb_io_capacity也好,效果都有限。

内存这块更直接。innodb_buffer_pool_size是InnoDB最重要的参数,它决定多少数据和索引能缓存在内存里。如果热数据总共20GB,你只给了8GB缓冲池,剩下12GB每次都要从磁盘读,再快的盘也扛不住频繁的随机读。

按我的经验,缓冲池设成物理内存的50%到70%比较稳妥。一台32GB内存的机器,给20GB左右是合理的。但前提是你得知道自己的热数据到底有多大,这个可以通过information_schema里的表大小估算。

CPU核数在并发高的时候才明显。单条SQL跑得慢,加核没用;但如果是几百个连接同时打进来,核数不够就会排队。这个取舍要看业务类型,OLTP和OLAP对CPU的需求完全不一样。

如果数据库跑在租来的服务器上,硬件选型这一步就得提前想清楚。拿秀米云的马来西亚服务器1来说,E3-1230配16G内存、20M带宽,月付99美元,跑个小规模的MySQL实例够用,但热数据超过10GB就要考虑往上走。稍微宽裕一点可以看马来西亚裸机云 VII,双E5-2650加32G内存,月付134美元,缓冲池能给到20GB左右,中小型业务基本吃得下。

配置层:几个真正值得动的参数

参数不是越多越好。MySQL有几百个可调项,但真正影响性能的就那么几个。改多了反而容易出问题。

  • innodb_buffer_pool_size:前面说过了,这是第一优先级。设小了磁盘压力大,设大了可能挤占系统内存导致swap,swap一上来性能直接崩。
  • innodb_log_file_size:默认值通常偏小,导致频繁checkpoint。适当加大能减少磁盘刷写次数,但太大又会让崩溃恢复变慢。一般设成1GB到2GB之间比较常见。
  • max_connections:设太高会让每个连接分到的内存变少,设太低又会有连接被拒绝。我一般会看业务实际的并发峰值,留30%余量就够,不用照着默认的151去改。

这里有个取舍:加大innodb_log_file_size能减少刷盘,但崩溃后恢复时间会变长。如果你的业务对可用性要求极高,恢复时间不能超过几十秒,那这个值就不能设太大。反过来,如果恢复时间不敏感,加大它能换来更平稳的写入性能。

还有一点,改完参数一定要重启验证,别只看配置文件里写了什么。有些参数是动态生效的,有些必须重启,搞混了会以为改了没用。

SQL层:索引不是越多越好

到了SQL这一层,问题往往更隐蔽。一条SQL在测试环境跑得飞快,上了生产就慢,多半是数据量上来了,执行计划变了。

explain是必须会用的。看type列,如果是ALL就是全表扫描,得加索引;看rows列,预估扫描行数太大也要警惕。但索引不是越多越好,每个索引都要占空间,写入时还要维护,一张表挂七八个索引,插入性能会明显下降。

复合索引的顺序很关键。比如where条件里既有status又有created_at,索引建在(status, created_at)上和(created_at, status)上效果完全不同。最左前缀原则要记牢,但也不用死记,explain一看就清楚了。

分页查询是另一个高频坑。limit 100000, 20这种写法,MySQL会先扫前100000行再丢掉,越翻到后面越慢。改成基于游标的分页,用where id > 上次最大id来定位,速度会稳定很多。

如果数据量到了单表几千万行,索引优化也救不了全表扫描的时候,就该考虑分库分表了。但这一步代价很大,应用层要改,运维复杂度也上去了。换我我会先确认是不是真的到了这个量级,很多时候加内存、调索引就能再撑一两年。

调优的终点是够用,不是极致

调优没有标准答案,只有适不适合当前业务。一个日活几千的小站,没必要照着大厂的标准去配参数。反过来,日订单几十万的系统,也不能靠一台16G内存的机器硬扛。

我的建议是先跑慢查询日志,定位到具体是哪几条SQL在拖后腿,再判断是加硬件还是改SQL。硬件层的瓶颈最难绕过去,但也不是一上来就要换机器。先把缓冲池调对,把该加的索引加上,很多时候问题就解决了。

如果确实需要换硬件,选的时候盯住内存容量和磁盘类型这两个点。内存决定缓冲池能开多大,磁盘决定随机读写能扛多少。CPU反而是最后才需要纠结的。像马来西亚大带宽服务器 III这种双E5-2683v4加64G内存、G口带宽的配置,月付358.50美元,适合热数据在30GB以上、并发写入比较频繁的场景,缓冲池可以给到40GB左右,磁盘压力会小很多。

最后说一句,调优是个持续的过程。业务在变,数据量在涨,今天够用的配置明年可能就不够了。定期看慢查询日志,比一次性调完就不管要靠谱得多。