MySQL调优到底调什么?从慢查询到硬件选型的完整思路

2026-10-09 20:49 1002 次浏览

先搞清楚瓶颈在哪一层,别急着改参数

很多人遇到数据库慢,第一反应是去搜「MySQL调优参数」,然后照着帖子把innodb_buffer_pool_size改大、把query_cache_size打开。改完发现没快多少,或者快了两天又回去了。

我一般会先让慢查询日志跑两天,看看慢的到底是哪几条SQL、扫了多少行、返回多少行。如果一条SQL扫了几十万行只返回十条,那是索引问题,跟参数关系不大。如果SQL本身没问题,但并发一上来就卡,那才轮到看参数和硬件。

判断顺序大致是这样:先用慢查询日志定位具体SQL,再看执行计划确认索引有没有走对,然后看服务器层面的指标——CPU是不是跑满了、磁盘IO有没有到瓶颈、内存够不够装下热数据。跳过前两步直接调参数,多数时候是在做无用功。

这里有个容易被忽略的点:慢查询日志本身会带来额外IO开销,在线业务量大时建议设long_query_time为1秒以上,别设0.1秒,否则日志文件涨得比数据还快。

参数里真正值得调的没几个

MySQL的参数有几百个,但生产环境里真正需要动的通常不超过五个。innodb_buffer_pool_size排第一,它决定InnoDB能缓存多少数据和索引在内存里。设得太小,每次查询都要读磁盘;设得太大,操作系统自己没内存可用,反而触发swap。

按我的经验,如果这台机器只跑MySQL,缓冲池可以设到物理内存的60%到70%。一台64G内存的机器,缓冲池给到40G左右比较稳妥。但前提是你的热数据总量没有超过这个数,否则加内存才是根本解法。

  • innodb_log_file_size:写密集场景适当调大,减少checkpoint频率,但别超过缓冲池的25%
  • max_connections:不是越大越好,连接数上去之后线程切换开销会把CPU吃光,通常几百到一千够用
  • innodb_flush_log_at_trx_commit:设1最安全,设2性能好一些但崩溃可能丢一秒数据,看业务能不能接受

query_cache_size这个参数在MySQL 8.0里已经被移除了,如果你还在用5.7并且开着查询缓存,高并发写入场景下它反而会成为瓶颈,因为每次写入都要失效相关缓存。

硬件这层绕不过去:什么时候该从云主机换到独立服务器

参数调到头了,SQL也优化过了,还是扛不住,那问题就在硬件。云主机的问题是IO和内存往往共享,邻居一忙你的磁盘延迟就飘。数据库对磁盘延迟特别敏感,一次随机读从0.1ms变成2ms,QPS可能直接掉一半。

我见过不少配置是这样的:业务跑在一台8核16G的云主机上,数据量到了几十G,缓冲池只能给8G,剩下的全靠磁盘扛。这种情况下继续调参数意义不大,换一台内存更大的机器才是正解。

如果是写密集或者数据量在百G以上,独立服务器的优势会明显一些。以秀米云的马来西亚裸机云 XIV为例,Gold 6133双路、64G内存、20M带宽,月付289美元,缓冲池能给到40G左右,热数据基本能全放内存。磁盘是独享的,不会因为邻居的IO把延迟拉高。

当然不是所有场景都需要独立服务器。数据量在10G以内、QPS几百的小业务,一台配置合理的云主机完全够用,没必要多花钱。判断标准很简单:如果缓冲池能装下全部热数据,并且磁盘IO没有持续跑满,就不用换。

写密集的场景还可以看马来西亚大带宽服务器 X,E5-2698v4双路、64G内存、300M带宽,月付478.50美元。带宽给得足,主从复制传输binlog不会成为瓶颈。这个配置适合数据量中等但写入频繁的业务,比如订单系统或者日志采集。

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

MySQL调优没有标准答案,同一个参数在不同业务上效果可能完全相反。我的建议是按这个顺序走:先看慢查询日志定位SQL,再看执行计划确认索引,然后调三五个核心参数,最后才考虑硬件。

如果数据量在50G以内、QPS在几千级别,一台16核32G的机器配上合理的索引基本能撑住。数据量过百G或者写入量很大,再考虑独立服务器,64G内存起步,缓冲池给到40G左右。别一上来就想着堆硬件,也别指望改几个参数就能解决所有问题。