线上慢查询出现时,很多人的第一反应是“给字段加索引”。索引当然重要,但事故处理中只盯 SQL,容易漏掉更关键的事:影响面有没有止住、功能能不能降级、缓存和读写路径是不是本来就设计错了。
一次典型慢查询可能从一个看起来很小的列表接口开始。比如查询最近参与用户,SQL 里既有 DISTINCT,又按时间排序,还只取前几条。没有合适索引时,数据库需要扫描、去重、排序,最后再 LIMIT。如果这个表正在高频写入,连接池和主库都可能被拖住。
先看影响面,不要直接进代码
第一步先确认告警范围:错误率是不是全站上升,是否只影响某个库分片,调用方是核心交易链路还是边缘展示功能。再看数据库连接、慢查询数、接口量、队列积压和业务指标。
这一步的目标不是找根因,而是判断要不要先止血。用户正在受影响时,先暂停非核心功能、关闭展示入口、降级接口或切换流量。不要一边让慢 SQL 继续跑,一边慢慢翻代码。
再拆 SQL 为什么慢
慢 SQL 要按执行顺序看:从哪里取数据、有没有过滤条件、是否去重、是否排序、是否能利用索引。DISTINCT + ORDER BY + LIMIT 很容易让人误判,因为 LIMIT 10 不代表数据库只读 10 行。
如果排序字段没有索引,数据库可能先扫大量数据,再去重和排序。即使加索引,也要确认查询字段和排序字段是否匹配,是否会回表,是否会产生临时表。
长效方案不只是索引
索引通常是必要修复,但不一定是完整修复。读多写多的展示数据,最好前置缓存;非强实时的榜单、最近参与用户、热门内容,可以接受几分钟延迟。这样高峰期不会让数据库承担每一次页面刷新。
还要补上降级开关和发布预案。一个边缘展示功能不应该拖垮核心链路。复盘时至少留下四类动作:SQL 改写、索引或表结构调整、缓存策略、功能降级和监控。
慢查询事故的经验是:加索引解决的是这一条 SQL,流程闭环解决的是下一次事故。




