一条 SQL 昨天还很快,今天突然变慢,你会怎么用 EXPLAIN ANALYZE 找到真正耗时的位置?
我的判断
昨天快今天慢,要比较真实参数和实际执行计划,找到估算偏差、扫描放大、排序或等待,而不是看到某个 key 就结束。
我会把昨天和今天的 SQL 指纹、绑定参数、返回行数、表数据量、索引和统计信息放在一起。很多“同一条 SQL”其实是今天来了一个超级租户或查了一整年,数据分布已经不同。
在只读副本或可控环境执行 EXPLAIN ANALYZE,沿算子看 actual rows、loops 和耗时:预计 10 行实际 100 万行,说明统计信息或列相关性有偏差;嵌套循环 loops 被放大,通常是连接顺序或驱动集有问题;扫描不多但耗时长,要转去看锁、IO 或连接等待,因为这些不一定完整体现在计划里。
重点会核对:
- 访问范围和返回行数比例;
- 是否大量回表、临时表或额外排序;
- 统计信息更新时间和直方图是否适合倾斜列;
- 当时 buffer pool、磁盘和锁等待是否变化。
修复可能是更新统计、调整联合索引、改写 SQL 或限制查询范围。FORCE INDEX 只会作为短期止损并经过多组参数验证,不会当永久答案。