阅读 EXPLAIN 执行计划
解读查询计划中的扫描类型、连接方法和成本估算。
阅读 EXPLAIN 执行计划 是 CoddyKit 上的免费 SQL Interview Prep 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Interview Prep 课程共包含 4 节课。
面试官为什么会问 EXPLAIN
当您进入高级职位面试后,面试官不再只问如何编写查询,而会开始问为什么这个查询很慢。能够回答这个问题的工具就是 EXPLAIN。
EXPLAIN 会显示数据库的执行计划:也就是规划器选择执行 SQL 时采用的逐步策略。它会揭示扫描了哪些表、以什么顺序连接这些表,以及每个步骤的大致开销。
能够读懂执行计划,说明您理解的是数据库引擎,而不只是语法。这正是面试官用来区分中级和高级候选人的能力。
EXPLAIN 与 EXPLAIN ANALYZE
这两种形式的区别是面试官非常喜欢考查的内容。
- EXPLAIN 会显示规划器的估算计划,但不会运行查询,速度快且安全。
- EXPLAIN ANALYZE 会实际执行查询,并将真实的行数和耗时与估算值一并报告。
最有价值的是比较估算行数和实际行数。两者差异很大,说明规划器使用的统计信息不准确,因此很可能做出了糟糕的选择。
请注意:EXPLAIN ANALYZE 会真实运行查询,因此除非将其包裹在会回滚的事务中,否则它会执行其中的 INSERT 或 UPDATE。
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;如何读取树状计划
执行计划是一棵树,而不是列表。缩进最深的节点是最先运行的叶节点;结果会逐层向上流向根节点,根节点产生最终输出。
请从内向外阅读:找到最深的节点,那里就是执行开始的地方。每个父节点都会接收其子节点输出的行。
在面试中,请按照这个顺序进行说明:首先扫描这张表,这些行进入这个连接,连接结果进入排序,排序结果再进入限制操作。面试官希望听到的正是这种自底向上的说明方式。
执行计划节点剖析
Postgres 中的每个执行计划节点都包含相同的关键数字:
- 成本=0.00..35.50 启动成本..总成本,以规划器的任意单位表示
- 行数=1000 估算生成的行数
- 宽度=64 估算的平均行大小,单位为字节
第一个成本是启动成本(第一行出现前所需的工作,例如构建哈希表)。第二个是返回所有行所需的总成本。总成本越高,表示规划器认为相对开销越大。
Seq Scan on orders (cost=0.00..35.50 rows=1000 width=64)实例演示
请考虑一个简单的带过滤条件的查询。下面的执行计划用一行就讲清了。
它在orders上执行顺序扫描(读取整张表),并应用过滤条件status = 'shipped'。规划器估算会得到 1000 个匹配行。
如果orders有 1000 万行,而只有 1000 行匹配,面试官希望您回答:这里使用顺序扫描很浪费;在状态列(或选择性更高的列)上建立索引,就可以避免读取整张表。
EXPLAIN SELECT * FROM orders WHERE status = 'shipped';
Seq Scan on orders (cost=0.00..18334.00 rows=1000 width=64)
Filter: (status = 'shipped'::text)估算行数与实际行数
使用EXPLAIN ANALYZE时,您还会在括号中看到实际数字。
请看这个示例:规划器估算有 1000 行,但实际得到了 480000 行。这意味着行数被低估了 480 倍。规划器假定行数很少,因此选择了相应的策略;对于真实数据来说,这个选择很可能是错误的。
在面试中,这个差距就是您的首要诊断结论:统计信息已经过时,请对该表运行 ANALYZE,之后规划器很可能会选择更好的执行计划。
Seq Scan on orders
(cost=0.00..18334.00 rows=1000 width=64)
(actual time=0.02..210.4 rows=480000 loops=1)循环次数=N 的含义
loops值比候选人预期的更加重要。它表示一个节点被执行的次数。
这个值会出现在嵌套循环连接的内侧:内层节点会针对外层的每一行运行一次。如果loops=480000,那么该内层步骤就执行了 48 万次。
重要的是:显示的每行耗时和行数都是每次循环的数据。要得到真正的总量,您需要乘以loops。一个每次循环耗时 0.004 毫秒、看起来很便宜的节点,在 480000 次循环中会累积到将近 2 秒。
Index Scan using idx_cust on orders
(actual time=0.003..0.004 rows=1 loops=480000)成本是相对值,而不是毫秒数
一个常见陷阱是:候选人看到cost=18334,就说这需要 18 秒。不对。
成本使用规划器的任意单位表示,并经过校准,使一次顺序页面读取等于 1.0。它仅适合用来比较执行计划,而不是表示实际耗时。
要了解真实耗时,您需要使用EXPLAIN ANALYZE及其actual time值,这些值以毫秒为单位测量。在面试中请清楚地说明这一点,这能表明您真正理解了这个指标。
读取连接执行计划
这是一个涉及两张表的执行计划。请从下往上读取。
前两个扫描步骤分别从orders和customers收集行。它们将数据提供给哈希连接:一侧构建哈希,另一侧探测哈希表。连接的输出随后进入最终结果。
请注意,缩进展示了结构:两个扫描步骤都位于哈希连接之下。面试官希望您指出连接方法(这里是哈希连接)以及哪张表被用于构建哈希表(通常是较小的那张表)。
Hash Join (cost=30.0..520.0 rows=900 width=72)
Hash Cond: (o.customer_id = c.id)
-> Seq Scan on orders o (cost=0..400 rows=10000)
-> Hash (cost=18..18 rows=500)
-> Seq Scan on customers c (cost=0..18 rows=500)需要指出的危险信号
请培养自己在任何执行计划中发现以下警告信号的能力:
- 对大表执行顺序扫描且带有高选择性的过滤条件,索引可能有所帮助。
- 估算行数与实际行数相差很大,说明统计信息已经过时。
- 嵌套循环的循环次数很高且处理的是大表,通常表示内层连接键缺少索引。
- 排序或哈希溢写到磁盘(显示为
Disk用量),说明work_mem太小。 - 按过滤条件移除的行数量非常多,说明您读取并丢弃了表中的大部分行。
输出格式与 BUFFERS
执行计划有多种格式。默认的TEXT格式就是您在面试中会朗读和分析的内容。不过,您也可以请求结构化输出。
EXPLAIN (FORMAT JSON)或FORMAT YAML会生成机器可读的执行计划,工具和仪表板可以对其进行解析。您很少需要手动处理这些格式,但知道它们的存在能体现您的资深水平。
请在括号中添加选项:EXPLAIN (ANALYZE, BUFFERS)。BUFFERS选项会报告缓存命中与磁盘读取的情况,对于诊断受 I/O 限制的查询非常有价值。
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = 42;快速检查
面试官向您展示了一个EXPLAIN ANALYZE节点,其中成本部分的rows=1000,但actual ... rows=480000。最可能的诊断是什么?
总结
现在,您已经能够像资深开发人员一样阅读执行计划:
EXPLAIN负责估算,EXPLAIN ANALYZE负责实际运行和测量。- 从下往上读取树形结构;叶节点先运行,根节点生成输出。
- 每个节点都会显示成本(相对单位)、行数和宽度;
actual time才是真实的毫秒数值。 loops会将每次循环的数值累加,遇到嵌套循环时要特别留意。- 估算行数与实际行数之间的差距,是最重要的诊断信号。
请大声讲解执行计划并指出危险信号,这正是面试中脱颖而出的表现。
常见问题解答
「阅读 EXPLAIN 执行计划」课时是免费的吗?
是的 — 「阅读 EXPLAIN 执行计划」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 SQL Interview Prep 课程共包含 4 节课。
「阅读 EXPLAIN 执行计划」这节课中我会学到什么?
解读查询计划中的扫描类型、连接方法和成本估算。 你通过在浏览器中直接运行的动手代码来练习 SQL Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 SQL Interview Prep 需要有经验吗?
无需任何先前经验。CoddyKit 上的 SQL Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「阅读 EXPLAIN 执行计划」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 SQL Interview Prep 课中编写并运行代码吗?
能。每节 SQL Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 阅读 EXPLAIN 执行计划
- 顺序扫描、索引扫描与仅索引扫描
- 连接算法:嵌套循环、哈希与归并
- 发现并修复慢查询