0Pricing
SQL Interview Prep · 课时

B 树索引及其作用

了解索引实际存储的内容,以及它能加速哪些操作。

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

面试官为什么会问索引

当面试官说“这个查询很慢,您会怎么做?”时,他们几乎总是在期待一个涉及索引的回答。索引是提升读取性能最重要的手段,因此它能区分出只是记住了语法的候选人,以及真正理解数据库如何查找行的候选人。

在本课中,您将建立一个关于B 树索引的精确心智模型:它存储什么、能加速哪些操作,以及如何像资深工程师一样讨论它。

索引解决的问题

没有索引时,查找符合条件的行会迫使数据库读取表中的每一行。这称为顺序扫描(或全表扫描)。在一个包含一百万行的表中,即使只有一行匹配,也意味着要检查一百万行。

索引是一种独立的有序数据结构,可以让数据库引擎直接跳转到匹配的行,就像书籍的索引让您无需阅读每一页就能找到某个主题一样。

-- No index: the engine reads ALL rows to find this one
SELECT * FROM users WHERE email = 'ada@example.com';

B 树实际存储什么

PostgreSQL、MySQL、SQL 服务器和大多数数据库引擎的默认索引都是B 树(平衡树)。它按照排序后的顺序存储被索引列的值,并将这些值组织成由多个页面组成的浅层树。

  • 每个叶节点都存有索引键,以及指向实际表行的指针。
  • 这棵树始终保持平衡,因此无论表的大小如何,每次查找只需访问少量页面。

一次查找大约经过 log(N) 个步骤,从根节点向下走到叶节点,而不是扫描全部 N 行。

创建您的第一个索引

您可以使用 CREATE INDEX 创建 B 树索引。请清晰地命名,这样审阅者一眼就能看出对应的表和列。

索引建立后,使用 email 进行筛选的查询就可以利用它,通过读取少量页面找到匹配的行,而不必进行全表扫描。

CREATE INDEX idx_users_email ON users (email);

-- Now this lookup uses the index instead of scanning
SELECT * FROM users WHERE email = 'ada@example.com';

B 树可以加速的操作

由于 B 树会让值保持有序,它能加速的操作远不止精确匹配。面试官会很喜欢您准确列出以下操作:

  • 等值匹配:WHERE email = ?
  • 范围查询:WHERE age > 30、BETWEEN、<、>=
  • 前缀匹配:WHERE name LIKE 'Ada%'(但 NOT '%da')
  • 对被索引列使用 ORDER BY,从而避免排序
  • MIN/MAX,因为它们位于有序结构的两端

示例:范围查询

请考虑一个包含数百万行的订单表。某个报表查询需要获取最近的订单。由于 created_at 上有索引,数据库引擎可以在有序索引中定位到范围起点,然后只向前读取所需的数据。

索引将全表扫描变成了有界范围扫描,只读取符合条件的那一部分数据。

CREATE INDEX idx_orders_created_at ON orders (created_at);

SELECT order_id, total
FROM orders
WHERE created_at >= '2026-01-01'
  AND created_at <  '2026-02-01';

索引也能帮助排序

一个经常被忽略的要点是:由于索引已经排好序,数据库引擎可以按照索引顺序返回行,并跳过单独的排序步骤。这对 ORDER BY 很重要,尤其适用于取前 N 条记录的分页。

如果您按照拥有匹配索引的列进行排序,优化器就可以按顺序读取索引,并在获取足够多的行后提前停止。

-- Index on created_at lets this avoid a sort and stop after 10 rows
SELECT order_id, total
FROM orders
ORDER BY created_at DESC
LIMIT 10;

隐藏成本:堆表读取

普通 B 树索引只存储被索引的列和行指针。因此,找到匹配的条目后,数据库引擎仍然必须前往表(堆)读取您选择的其他列。

这第二次跳转就是堆表读取。对于少量行来说成本很低,但当查询匹配大量行时,成本就会很高;这也是低选择性索引有时会被忽略的原因之一。(稍后您会看到覆盖索引如何解决这个问题。)

确认索引已被使用

不要声称索引已被使用,而要用 EXPLAIN 证明这一点。在面试中,讲述执行计划能够展示您真正的理解。

  • Seq Scan 表示没有使用索引。
  • Index Scan 或 Index Seek 表示使用了索引。

如果您添加了索引却仍然看到顺序扫描,说明规划器判断扫描成本更低,通常是因为查询匹配了表中比例过大的数据。

EXPLAIN
SELECT * FROM users WHERE email = 'ada@example.com';
-- Look for: Index Scan using idx_users_email

主键已经建立索引

一个常见的面试陷阱是:声明 PRIMARY KEY 或 UNIQUE 约束会自动创建配套的 B 树索引。您不需要、也不应该在同一列上再添加第二个索引。

这就是为什么基于主键的连接和查找本来就很快,也解释了为什么“我应该给标识列建立索引吗?”通常是个陷阱——系统已经替您完成了。

-- This already builds a unique B-Tree index on (id)
CREATE TABLE users (
  id    BIGINT PRIMARY KEY,
  email TEXT UNIQUE
);

面试时如何表述

您可以用一句简洁的话把要点串起来,让面试官听得明白:

“B 树索引是一种有序的平衡结构,能够让数据库引擎通过 log(N) 次页面读取找到行,而不必扫描整张表。它可以加速被索引列上的等值、范围、前缀和 ORDER BY 操作,但每个匹配项仍然需要为非索引列执行一次堆表读取。”

然后用 EXPLAIN 为这句话提供依据。模型加证据,这种组合才能获得面试分数。

快速检查

测试您对 B 树索引能够加速哪些操作的心智模型。

回顾:B 树索引

请记住以下要点,并带入下一课:

  • B 树在平衡树中按排序后的顺序存储被索引的值,从而实现 log(N) 次查找。
  • 它可以加速等值匹配、范围查询、前缀(前导) LIKE、ORDER BY 以及 MIN/MAX。
  • 每个匹配项仍然需要为不在索引中的列执行一次堆表读取。
  • 使用函数包裹列,或使用前导通配符,会使索引失效。
  • 始终使用 EXPLAIN 进行验证;PRIMARY KEY 和 UNIQUE 约束会自动建立索引。

下一节:当一个索引同时覆盖多个列时,如何排列这些列的顺序。

常见问题解答

「B 树索引及其作用」课时是免费的吗?

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

「B 树索引及其作用」这节课中我会学到什么?

了解索引实际存储的内容,以及它能加速哪些操作。 你通过在浏览器中直接运行的动手代码来练习 SQL Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Interview Prep 需要有经验吗?

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

「B 树索引及其作用」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. B 树索引及其作用
  2. 复合索引的列顺序
  3. 覆盖索引与仅索引扫描
  4. 索引何时有害:写入与选择性
← 返回 SQL Interview Prep