加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_常德站长网 (https://www.0736zz.com/)- 媒体处理、CDN、边缘计算、网络安全、物联网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL性能优化实战:慢查询到毫秒响应全链路突破

发布时间:2026-10-12 12:19:56 所属栏目:MySql教程 来源:DaWei
导读:  去年冬天那台阿里云的RDS,CPU压到90%的时候,我原以为调调索引就能搞定,结果凌晨三点在监控大屏前盯着慢查询日志,发现全表扫描的SQL根本没走索引——不是索引没建,是统计信息过期了。这事儿后来被老张骂得狗血淋头,他说

  去年冬天那台阿里云的RDS,CPU压到90%的时候,我原以为调调索引就能搞定,结果凌晨三点在监控大屏前盯着慢查询日志,发现全表扫描的SQL根本没走索引——不是索引没建,是统计信息过期了。这事儿后来被老张骂得狗血淋头,他说“你搞了十几年优化,连ANALYZE TABLE都不记得跑?”我嘴硬说“谁家生产环境天天跑这个”,结果他直接甩出他们组去年的事故报告:统计信息滞后导致主从延迟12小时,最后靠强制主备切换才兜住。

  说到这,得扯回今天要吐槽的“全链路突破”。上个月帮一个电商客户优化订单查询,他们用的是MySQL 8.0,慢查询日志里全是“Using filesort”和“Using temporary”。我第一反应是索引覆盖不够,但EXPLAIN一看,好家伙,联合索引(user_id, status, create_time)明明能覆盖,结果执行计划选了全表扫描——后来查出来是优化器参数optimizer_switch里“condition_fanout_filter”没开。这事儿让我有点后怕,因为之前总听人说“8.0的优化器更智能”,结果真碰上这种老毛病变本加厉的案例:参数没调对,智能优化器反而选了更蠢的执行计划。

  车间那台风扇一直在响,旁边小李抖着腿刷手机,突然说了句“你们有没有试过把SQL_BIG_RESULT加上?”我抬头看他一眼,手套上还粘着昨天拆服务器时留下的硬胶块。这招其实我在MySQL 5.7就玩过,对大结果集的排序确实能触发磁盘临时表,但8.0里优化器更激进,有时候反而会因为估算不准走错路。我让他先在测试环境跑,结果他手机在铁台上震了一下——是媳妇催他回家带孩子。

  中午盒饭里有块姜,我挑出来扔桌上,继续说“全链路突破”里最站得住的部分:优胜劣汰。去年冬天那台RDS,最后不是靠调索引或参数搞定的,是直接砍了30%的冗余查询——业务方说“这些接口没人用”,我让他们拿日志证明,结果真有5个接口近三个月调用次数为0。这事儿让我明白,优化到⭐️⭐️⭐️⭐️拼的不是技术,是敢不敢砍业务。老张后来补了句:“你们这些搞优化的,总想着怎么让烂SQL跑得快,怎么不想想怎么让烂SQL别跑?”

  其实我也没拆到底。比如那个电商客户的订单查询,最后发现真正拖慢响应的是应用层的N+1查询——前端传了100个order_id,后端用for循环查100次订单详情。这事儿MySQL再怎么优化也没用,得改代码。但客户死活不肯改,说“历史包袱太重,改不动”。我原以为他们是在找借口,结果看了他们的代码仓库,发现最早的订单查询逻辑是2015年写的,当时用的还是MySQL 5.1,连批量查询的语法都不支持。这个型号我只在别人那儿见过——那种“历史包袱比服务器还重”的架构。

文章配图,仅供参考

  下午三点半,谁把扳手掉地上了一声闷响。小李突然说:“你们说‘全链路突破’,是不是包括把慢查询的锅甩给网络?”我笑了,这招我十年前就玩过——当时客户说查询慢,我让他们用tcpdump抓包,发现从应用服务器到数据库的网络延迟有200ms。后来查出来是交换机端口被限速了,但客户为了省事,直接把锅甩给“MySQL性能不行”。这个我敢打包票,至少一半的“MySQL慢”问题,最后查出来是网络或应用层的锅。

  说到甩锅,我想起去年帮一个金融客户优化风控查询。他们说“MySQL扛不住高并发”,我让他们提供压力测试数据,结果发现并发才500的时候,数据库连接池就满了。后来查出来是应用代码里没做连接复用,每个请求都新建连接。这事儿让我明白,优化到⭐️⭐️⭐️⭐️拼的不是技术,是基本功——连连接池都不会配,还谈什么高并发?老张后来补了句:“你们这些搞优化的,总想着怎么让烂架构跑得快,怎么不想想怎么让烂架构别存在?”

  手机又震了,这次是测试组发消息:“你那条优化后的SQL,在压测时出现锁等待超时。”我头皮一麻,赶紧登服务器看processlist——好家伙,有个事务持有了订单表的行锁,一直没提交。这个我说不准,要看运气——如果那个事务刚好在压测高峰期执行,就会触发连锁反应。我让测试组先停压,自己去查事务日志,结果发现是定时任务在跑数据同步,忘了加事务超时参数。这事儿让我后怕,因为之前总听人说“优化要全链路”,结果真碰上这种“链路里有个定时炸弹”的案例,再怎么优化也没用。

  最后说回“全链路突破”里最实用的部分:监控。去年冬天那台RDS,要不是有Prometheus+Grafana的监控,我根本发现不了统计信息过期的问题——因为CPU没爆,QPS也没降,就是慢查询变多了。后来我让他们把“索引使用率”和“统计信息年龄”也加到监控里,结果这个月真的预警了两次:一次是统计信息超过7天没更新,一次是某个索引的使用率突然降到10%以下。这个我敢打包票,监控比优化更重要——优化是事后补救,监控是事前预防。

  明天我要去客户现场,帮他们把那条锁等待超时的SQL改掉。其实我也没底——不知道他们的事务隔离级别是不是READ COMMITTED,不知道他们的锁超时时间设的是多少,不知道他们的应用代码里有没有隐藏的死锁。但不管怎样,先改了再说——优化这事儿,本来就是试错的过程。就像老张说的:“你搞了十几年优化,还没明白吗?没有银弹,只有不断试。”

(编辑:应用网_常德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!