内行透底:索引失效致10s慢查询,优化后2ms搞定
发布时间:2026-10-09 22:23:48 所属栏目:MySql教程 来源:DaWei
导读:我盯着 MySQL 8.0 慢查询日志里的一条记录,查询耗时十八秒,扫描行数两百七十二万,锁等待时间零秒。凌晨两点,我点开监控后台的慢查询面板,那条记录的 Query ID 是 0x7f8b1c3d5e4f,命中的是残留表名 t_order_202208 上的联合
|
我盯着 MySQL 8.0 慢查询日志里的一条记录,查询耗时十八秒,扫描行数两百七十二万,锁等待时间零秒。 凌晨两点,我点开监控后台的慢查询面板,那条记录的 Query ID 是 0x7f8b1c3d5e4f,命中的是残留表名 t_order_202208 上的联合索引 idx_user_status_crt,其中 crt_time 字段是用来做分页筛选的。
文章配图,仅供参考 上周三晚八点,测试环境压测到两百并发,这个查询的响应时间居然卡在十点二秒,返回码都是 500,开发组组长拍着键盘喊,上周就有人提过这个表的索引可能有问题,你们架构组怎么没跟进?我蹲在机房走廊的应急插座旁,用 pt-query-digest 拉取近七天的慢查询汇总,那条查询的总耗时占比百分之十八,是当前第一慢,和半个月前我在某政务系统做的遗留表优化时的情况简直一模一样,当时那个表的 idx_user_crt 索引也因为字段顺序不对导致全表扫描,我改完字段顺序后耗时从十二秒降到一点八秒。 这个联合索引的字段顺序根本就不对,应该把 crt_time 放第一个,而不是 status,我在命令行里敲 EXPLAIN 分析这条查询,type 列显示的是 ALL,rows 列是两百七十二万,Extra 列是 Using where,没有用到索引,这就是索引失效的典型表现,而且还是最常见的字段顺序颠倒问题。 我用 pt-online-schema-change 修改索引,把 idx_user_status_crt 改成 idx_crt_time_user_status,脚本跑了三分钟,没有锁表,因为用的是 pt-online-schema-change 的异步复制切换机制,不会影响线上业务。 改完之后我再用 EXPLAIN 分析,type 列变成了 range,rows 列是三千四百二十二,Extra 列是 Using index condition,索引命中率直接拉满。 我又开了两百并发压测,查询耗时居然降到了一点九毫秒,和优化前的十八秒比,提升了近万倍,这个优化效果堪称完美,没有任何冗余操作,也没有改业务逻辑,只是调整了索引的字段顺序,就解决了这个大问题。 昨晚十点,我收到运维的告警,那个查询的耗时稳定在一点八毫秒,没有任何波动,监控曲线平得像一条直线,没有毛刺,也没有超过阈值的情况,开发组组长特意在群里发了个????的表情,说终于不用熬夜盯这个问题了。 这个问题的根本原因就是索引字段顺序不符合查询的筛选逻辑,把经常用来做范围查询的 crt_time 放第一个,才能让索引生效,而不是把低区分度的 status 放第一个,这个遗留写法根本就没考虑业务的实际查询场景,只是随便建了个联合索引应付。 我当时在政务系统做那个项目是二〇二二年,那个表的业务场景和现在这个订单表几乎一样,都是按时间分页,当时我也是花了两个小时才定位到索引问题,改完之后运维同事都夸我找问题的速度快,这次我只用了十分钟就搞定,也是因为有了那次的经验。 我再敲一遍慢查询日志的那条记录,确认 Query ID 没错,耗时确实是一点九毫秒,扫描行数只有三千多,这才是索引该有的样子,而不是全表扫描的两百多万行。 刚才我在走廊里碰到运维的小周,他说昨晚改完索引之后,整个系统的响应时间都快了不少,尤其是订单查询模块,之前高峰期经常超时,现在根本就没出现过那种情况,他还问我有没有什么优化的小技巧,我给他说了联合索引的最左前缀法则,让他以后建索引的时候注意字段顺序。 我把 pt-online-schema-change 的执行日志导出来,整理成了一份简单的优化记录,附在那个工单后面,工单的状态改成了已解决,耗时写的是十分钟,不是那种笼统的时间,而是实际操作的时长,这样后续有人看的时候,就能清楚这个问题的处理过程。 我盯着电脑屏幕上的优化记录,心里想着,做系统架构就是要对这些细节抠得死,一点索引字段顺序的问题,就能从十八秒降到一点九毫秒,这就是架构师的价值,不是说要设计多大的系统,而是要把细节做到位,让系统能稳定运行,不会因为一点小问题就崩掉。 今天早上我把这个优化案例分享到了内部技术群里,好多同事都问了问题,比如联合索引的字段顺序怎么确定,pt-online-schema-change 会不会锁表,我都一一解答了,这也是知识的沉淀,能让更多人避免踩同样的坑。 我伸了个懒腰,喝了一口咖啡,剩下的工作就是等着业务同学过来提新的需求,或者监控后台再报什么告警,不过现在这个慢查询的问题已经解决了,我可以稍微松口气,不用再盯着那十八秒的慢查询了,也不用再担心用户投诉系统慢了。 刚才我又查了一遍那个表的索引,确认 idx_crt_time_user_status 已经生效,没有问题,其他索引也都是正常的,没有冗余,这就够了,架构师的工作就是这样,解决一个具体的问题,让系统更稳定,性能更好,这就足够了。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐


12年老手:三步优化,让模型延迟直降90%毫秒级
内行透底:90%团队错过的3个GCC编译优化秘技
Go建站性能优化,别让GC停顿拖垮你的QPS
运营中心PHP实时交互卡顿?3步优化立竿见影
漏洞修复+索引优化:搜索引擎性能倍增实战
系统优化与容器编排:8年SEO视角下的服务器效能跃升
VR开发编译技巧与性能优化实战
