📄 一句话概括
索引=为查询专修的「目录页」:用一棵有序结构把「翻遍全表」变成「直奔目标」——代价是写入变慢、磁盘变鼓。
📝 本节和前面几节的关系
7-6 把慢查询的病认清了(全表扫描),本节开特效药。它也是第三章埋的伏笔的总回收:PRIMARY KEY(4-12)自带索引、UNIQUE(4-10)靠索引实现、FOREIGN KEY(4-13)的查找同样吃索引红利——主键查询快,从来不是白来的。
一、索引是什么
- 数据库内部维护一棵有序结构(B 树):查
name = '波仔'不用翻全表,而是像查字典一样按序二分直奔 - 建法:
CREATE INDEX idx_books_title ON books(title); - 何时自动有索引:主键(4-12)、UNIQUE 约束(4-10)——约束的「检查速度」正是靠索引
二、索引的代价(没有免费的目录页)
| 收益 | 代价 |
|---|---|
| 查询(SELECT)大幅加速 | 占额外磁盘空间 |
| 排序/去重受益 | 每次 INSERT/UPDATE 都要同步维护——写入变慢 |
所以索引是给高频查询列建的,不是见列就建: WHERE、JOIN、ORDER BY 里常出现的列才值得。
三、动手 Demo:亲测索引前后
-- 用 7-6 的 big 表(1 万行即可)
-- ① 没索引时查 name
SELECT * FROM big WHERE name = 'user_9527'; -- 全表扫描
-- ② 建索引
CREATE INDEX idx_big_name ON big(name);
-- ③ 再查同一句
SELECT * FROM big WHERE name = 'user_9527'; -- 走索引,几乎瞬回
-- ④ 看执行计划(EXPLAIN QUERY PLAN 是 SQLite 的 EXPLAIN)
EXPLAIN QUERY PLAN SELECT * FROM big WHERE name = 'user_9527';
-- 建索引前:SCAN big(全表扫描)
-- 建索引后:SEARCH big USING INDEX idx_big_name(走索引)
【准备块】7-6 的 big 表;重点看 EXPLAIN 输出里 SCAN → SEARCH 的变化。
四、30 秒实验
翻一本 600 页的书找「事务」:没目录翻一晚上,有目录 10 秒——但每次作者改版,目录也得重印。这就是「读快写慢」的全部真相。
五、常见误区
- 「建了索引就一定快」:列上套函数(7-6)、
LIKE '%开头'模糊查询都会让索引失效——建完要用 EXPLAIN 验证 - 「给所有列都建上」:写入被拖垮、磁盘被吃光;索引按查询频率取舍
- 「主键查询快是理所当然」:那是主键自带索引(4-12),不是理所当然——理解这点才算懂索引
自测三问
1. 索引加速什么、拖慢什么?(加速 SELECT/排序;拖慢 INSERT/UPDATE 并占空间) 2. 哪些列值得建索引?(WHERE/JOIN/ORDER BY 高频出现的列,按查询频率取舍) 3. `PRIMARY KEY` 和索引什么关系?(主键自动创建唯一索引——约束的速度靠索引兑现)- ☐ 下一节(7-8 纵向扩展、横向扩展-均衡负载)
相关笔记
- 慢查询-执行时间较长的SQL语句 —— 上一节诊断出病,本节下特效药
- PRIMARY KEY、主关键字、主键-使记录可以进行唯一识别 —— 主键查询快的真正原因
- 纵向扩展、横向扩展-均衡负载 —— 下一节:索引救不了时,靠扩展扛量
- 🗄️ 数据库基础 · 索引 —— 全课路线图