一条慢 SQL 的解剖学:诊断、拆解与修复
来源:dev.to — 2026-09-14
📋 概述
每个后端开发者都经历过那个瞬间:用户反馈看板加载很慢,翻日志发现一条查询跑了 3000 毫秒以上。本地三行测试数据下一切瞬时而在生产环境百万行数据前,这条未优化的查询能把整个应用拖垮。文章按数据库引擎真实处理查询的顺序展开:解析与翻译器校验语法、检查表与列是否存在;重写器做逻辑优化,比如把子查询改写成 JOIN;查询优化器根据统计信息生成执行计划,选出「最便宜」的取数路径;执行引擎再去磁盘或缓冲池取数据。作者指出查询慢时 99% 的原因是优化器选到了次优执行计划,通常是被缺失索引、过期统计信息或糟糕的查询写法逼的。诊断手段是 EXPLAIN ANALYZE,重点盯两个红旗:大表上的 Seq Scan 意味着从头到尾读每一行,以及估算行数与实际行数严重偏离——那说明统计信息过期,优化器可能选了 Nested Loop 这种灾难性策略而不是 Hash join。
🔑 核心要点
- 查询生命周期分四步:解析翻译、重写器、查询优化器、执行引擎。
- 慢查询 99% 归因于优化器选择了次优执行计划,诱因是缺索引、统计过期或查询写法差。
- 第一个红旗是 Seq Scan:在千万行大表上意味着读完每一行,哪怕你只想要其中 5 行。
- 第二个红旗是估算与实际严重偏离,例如估算 5 行实际 50 万行,会诱使优化器放弃 Hash join 改用 Nested Loop。
- 诊断原则是别猜:先用 EXPLAIN ANALYZE 让数据库自己说出它走的执行步骤与实际耗时。
- 索引的本质类似书末索引,B-Tree 让查找从 O(n) 变成 O(log n);复合索引还要遵守最左前缀规则。
💡 金句
永远不要猜查询为什么慢,直接问数据库:让它说出自己走过的执行步骤和真实耗时。
👍 0
👎 0
← 返回 dev.to 首页