慢 SQL 怎样排查?先区分执行慢、锁等待和连接排队
接口慢不等于 SQL 执行慢
一次数据库调用可能经历连接池排队、网络传输、锁等待、执行和结果读取。接口耗时很长,却只看见数据库执行很快时,先检查时间统计覆盖哪一段。缺少分段证据,就容易把应用连接池问题误判为索引问题。
记录真实 SQL 模板、参数类型、调用频率和受影响范围,同时保护敏感数据。偶发单次慢与所有请求持续慢,调查方向也可能不同。
先看查询做了多少工作
取得表结构、数据量、索引定义和执行计划,查看访问方式、选择的索引、估算行数、排序与临时表。关注扫描行数与返回行数是否差距很大,以及关联顺序是否让中间结果膨胀。
计划出现 Using filesort 不代表一定写了磁盘,也不代表必须立刻加索引;需要结合实际行数、内存与耗时判断。查询只返回少数行,也可能在过滤之前读了大量数据。
再检查等待与数据变化
如果同一查询平时快、事务高峰时慢,检查是否等待行锁或元数据锁,以及是否有长事务持有资源。慢事务可能由应用在事务中调用外部服务造成,单纯加索引无法解决持锁过久。
执行计划还可能受到数据分布和统计信息影响。测试库数据少、分布均匀时表现良好,不代表生产环境也相同。比较计划时必须保留参数和数据特征,避免只对比 SQL 文本。
选择改动最小的修复
先考虑减少无用字段、限制返回范围、改写不利于索引的条件,再评估索引列顺序和覆盖需求。深分页可能需要改为基于稳定排序键的游标分页,但这会改变接口语义,必须确认翻页需求。
索引会增加写入和存储成本,不能只看一次查询变快。EXPLAIN ANALYZE 会执行语句,使用前确认版本、语句与环境;生产排查避免为了获得数据而执行高成本实验。
验证与回滚
用代表性参数比较修复前后的计划、实际读取、耗时与写入影响。观察目标查询改善之外,是否增加锁等待或让其他关键 SQL 变差。结构变更使用现有发布流程,明确回滚方式,而不是在线反复试索引。
本文没有运行具体优化测试。面试时讲一个有证据的排查过程:“慢在哪里、发现什么、为何这样改、怎样验证”。没有实际数据时说明测量方法,不编造优化倍数,也不把强制索引作为通用答案。