2026-09-21 09:42 1007 次浏览

MySQL调优别急着改参数,先把这几件事做对

很多站长一遇到MySQL慢查询就狂调my.cnf,结果越调越乱。本文从慢日志分析、索引设计、SQL写法到硬件选型,梳理一套可落地的调优顺序,帮你少走弯路。

先搞清楚慢在哪,别上来就改配置

很多人的调优流程是这样的:网站变慢,打开my.cnf,把innodb_buffer_pool_size调大,把max_connections拉高,重启,然后发现该慢还是慢。问题在于,你连慢在哪都不知道。

第一步永远是开慢查询日志。设置long_query_time=1秒,跑一两天,用mysqldumpslow或者pt-query-digest统计。通常你会发现,80%的耗时集中在少数几条SQL上。先解决这几条,比改一百个参数都管用。

另外,用SHOW PROCESSLIST看看有没有长时间处于Sending data或Locked状态的查询。如果是锁等待,那就不是调优能解决的,得看业务逻辑有没有长事务。

索引不是越多越好,得看查询模式

慢查询定位到具体SQL之后,用EXPLAIN看执行计划。重点看三列:type、rows、Extra。type出现ALL就是全表扫描,rows数字大得离谱说明索引没走对,Extra里出现Using filesort或Using temporary就要警惕。

建索引有几个实战原则:

  • 联合索引遵循最左前缀,把区分度高的列放前面
  • 范围查询后面的列用不上索引,比如where a=1 and b>2 and c=3,c就用不到
  • 覆盖索引能避免回表,select的列尽量都在索引里
  • 频繁更新的列别乱建索引,写入放大很要命

还有一点,用LIKE '%xxx'开头的模糊查询,索引基本失效。这种场景要么上全文索引,要么换搜索引擎。

SQL写法上的几个隐形坑

同样的逻辑,写法不同性能差几十倍。比如在where里对字段做函数运算,像WHERE DATE(create_time)='2026-01-01',索引直接废掉,改成范围查询才行。

再比如隐式类型转换,user_id是varchar,你写WHERE user_id=123,MySQL会把字符串转成数字,索引失效。这种坑在代码里特别常见,尤其是ORM框架自动生成的SQL。

分页也是重灾区。LIMIT 100000,20这种深分页,MySQL要扫10万行再丢掉。优化方式是记住上次的最大ID,用WHERE id > last_id LIMIT 20。

硬件和架构层面别忽略

参数调优和SQL优化做完,如果还是扛不住,就要看硬件了。磁盘IO是MySQL最常见的瓶颈,机械盘换成SSD,QPS可能翻几倍。内存要够大,让热数据能全部缓存在buffer pool里。

如果单机确实到顶了,考虑读写分离或者分库分表。但别一上来就搞分布式,很多业务量根本没到那个程度,先把单机榨干再说。

数据库对IO和内存敏感,选服务器时别只看CPU核数。像马来西亚裸机云 XIII这类配置,E5-2698v4双路加64G内存,跑中大型数据库比较稳,机房在吉隆坡,适合东南亚业务落地。如果预算有限,马来西亚裸机云 II的E5-2650配32G也能撑住中小站点。