0Pricing
SQL Academy · 课时

顺序扫描与索引扫描

了解什么时候顺序扫描已经足够,什么时候必须使用索引扫描,以及规划器如何做出决定

顺序扫描与索引扫描 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

查找行的两种方式

数据库有两种读取行的基本策略:

  • 顺序扫描 — 读取表的每个页面
  • 索引扫描 — 遍历索引并获取匹配的行

顺序扫描适用的情况

如果无论如何都需要读取表中的大多数数据,那么扫描比读取索引并获取每个匹配行更便宜。大致来说:超过约 10–20% 的行 → 顺序扫描更优。

索引扫描更优的情况

对于选择性较高的查询(只涉及少量行),索引能够发挥作用:

EXPLAIN SELECT * FROM users WHERE id = 42;
-- Index Scan using users_pkey  (cost=0.43..8.45 rows=1)

EXPLAIN SELECT * FROM users WHERE active;
-- Seq Scan on users  (cost=0.00..15000.00 rows=950000)
-- (because most users are active)

索引扫描与仅索引扫描

有时索引本身就包含您需要的所有列,因此不需要读取表。这就是仅索引扫描:

CREATE INDEX users_email_id_idx ON users(id) INCLUDE (email);

EXPLAIN SELECT email FROM users WHERE id = 42;
-- Index Only Scan using users_email_id_idx

位图索引扫描

对于中等选择性的查询,PostgreSQL 可能会先为匹配的行建立位图,再按物理顺序获取这些行,这比随机输入/输出更快:

EXPLAIN SELECT * FROM orders WHERE status = 'pending';
-- Bitmap Heap Scan on orders
--   Recheck Cond: (status = 'pending')
--   -> Bitmap Index Scan on orders_status_idx

规划器选择顺序扫描的原因

常见原因包括:

  • 过滤列上没有索引
  • 索引无法使用(列上使用了函数、包含 OR 子句或类型不匹配)
  • 预计行数太多,使用索引不划算
  • 统计信息已过期,规划器错误地判断了选择性

谨慎强制使用索引

您无法直接向 PostgreSQL 提供提示。可以改为:

  • 运行 ANALYZE 以刷新统计信息
  • 添加合适的索引
  • 设置会话参数:使用 SET enable_seqscan = off; 进行诊断(不要用于生产环境)

可使用索引的谓词

要让索引发挥作用,WHERE 条件必须能够直接使用索引,也就是直接比较索引列:

-- GOOD:
WHERE created_at >= '2024-01-01'

-- BAD (function on the column):
WHERE date_trunc('day', created_at) = '2024-01-01'

-- BAD (cast):
WHERE created_at::DATE = '2024-01-01'

-- FIX: add a functional index, or rewrite with range.

复合索引的顺序

包含 (a, b) 的索引可以帮助仅查询 a 或同时查询 a AND b 的语句,但不能帮助仅查询 b 的语句。

索引大小很重要

包含热点键的窄 B 树索引可能完全保留在内存中,而宽索引则不一定。索引越小,速度越快。

验证计划

添加索引后,运行 EXPLAIN ANALYZE,确认规划器确实在使用它。如果没有使用,请继续查找原因。

回顾

选择顺序扫描还是索引扫描取决于选择性。

  • 过滤条件选择性高 → 索引扫描
  • 涉及表中大多数数据 → 顺序扫描
  • 中间情况使用位图扫描
  • 注意条件是否能够使用索引

快速检查

为什么 PostgreSQL 可能会选择顺序扫描,而不是使用已有索引?

常见问题解答

「顺序扫描与索引扫描」课时是免费的吗?

是的 — 「顺序扫描与索引扫描」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「顺序扫描与索引扫描」这节课中我会学到什么?

了解什么时候顺序扫描已经足够,什么时候必须使用索引扫描,以及规划器如何做出决定 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「顺序扫描与索引扫描」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 阅读 EXPLAIN 与 EXPLAIN ANALYZE
  2. 顺序扫描与索引扫描
  3. 哈希连接、合并连接与嵌套循环
  4. 识别并修复慢查询
← 返回 SQL Academy