一条 SQL 干掉 8 秒卡顿,只因改了一个索引
一条 SQL 干掉 8 秒卡顿,只因改了一个索引上周五晚上十一点,线上告警突然炸了,用户反馈下单接口卡成 PPT。打开慢查询日志一看,一条最普通的订单查询 SQL 居然跑了 8 秒多。当时我脑子里只有一个念头:这条 SQL 我上周才写的,测试环境明明只要 200 毫秒啊。排查了一整晚,最终发现问题出在一个谁都会忽略的索引细节上。改完之后查询直接掉到 50 毫秒以内,整个人都轻松了。今天我就把这次排查的全过程写出来,全是实战经验,没有一句废话。数据库索引策略与SQL优化实战:从 Explain 分析到毫秒级调优一、慢查询这件事,为什么总是在上线之后才爆做开发这些年,我发现一个规律:慢查询从来不在测试环境出问题,它永远在生产环境、在数据量最大的时候、在老板最关心的那个接口上准时爆发。根本原因其实就一个——测试环境的数据量和生产环境完全不是一个量级。你在测试库跑 10 万条数据觉得很快,但生产库 500 万条数据一上来,同样的 SQL 性能可能差几百倍。慢查询的根源说白了就那么几种:1、全表扫描。WHERE 条件里的字段压根没建索引,MySQL 只能老老实实一行一行地扫,数据量一大就彻底废了。2、索引建了但没用上。比如给性别字段建了索引,但这个字段只有男和女两个值,区分度太低,优化器一算觉得全表扫描更划算,索引就白建了。3、多表 JOIN 的时候驱动表选错了。小表驱动大表和大表驱动小表,性能差距可以非常大。4、隐式类型转换。字段是 varchar 类型,你偏偏用数字去比,索引直接报废,这个坑我自己踩过不下五次。5、函数包住了字段。比如 WHERE YEAR(create_time) = 2024,索引直接失效,因为 MySQL 没办法对函数结果建索引。这些问题单独拿出来看都不复杂,但真正排查的时候,大多数人就是卡在"不知道从哪里入手"。别急,下面我用一个真实案例,带你从头到尾走一遍。二、用 Explain 拆解慢查询:每个字段都有它的故事Explain 是 MySQL 给我们的一把手术刀,但很多人只会看 type 那一列,其他字段基本不管。实际上,Explain 的每一列都在告诉你一些关键信息。我先把最重要的几个字段列出来,后面实战的时候会一个一个对照着看。字段名 含义 重点关注什么id 查询执行序