全书目录

第十八篇:MySQL 完全指南 —— 城市户籍总账宇宙

第八章:索引 —— 户籍总账楼里的目录卡系统

1 分钟 385 字 第 343 / 962 个阅读单元

没有索引时,MySQL 查数据像馆员从第一页翻到最后一页。

有索引时,像先查目录卡,再去准确定位。

text
没有索引
SELECT -> 从第 1 行翻到最后 1 行

有索引
SELECT -> 先查目录卡 -> 定位到记录 -> 取出目标行

最常见的索引是 B-Tree 索引。你可以这样建:

sql
CREATE INDEX idx_citizens_household_id
ON citizens (household_id);

CREATE INDEX idx_citizens_household_status
ON citizens (household_id, status);

CREATE INDEX idx_households_district_status
ON households (district_id, status);

索引不是越多越好,因为它有成本:

  • 占空间
  • 写入要维护
  • 更新要维护
  • 删除也要维护

所以索引的本质是:

用空间和写入成本,换读取速度。

复合索引尤其重要。比如:

sql
CREATE INDEX idx_citizens_household_status
ON citizens (household_id, status);

它更适合这类查询:

sql
SELECT *
FROM citizens
WHERE household_id = 1
  AND status = 'active';

也常常能用于:

sql
SELECT *
FROM citizens
WHERE household_id = 1;

但未必适合只查:

sql
SELECT *
FROM citizens
WHERE status = 'active';

这就是常说的左前缀思维:复合索引更像按顺序排好的目录卡。

再看两个关键事实:

1. 唯一索引不等于主键

sql
national_id CHAR(18) NOT NULL UNIQUE

这是业务唯一号;而 citizen_id 才是表的主编号。

2. 外键关系也需要索引意识

MySQL 对外键相关列要求可高效检查,必要时会建立可用索引,但你不能因此放弃索引设计思考。真正决定查询性能的,仍然是你的访问模式。

一句话记忆:

索引不是“给字段贴加速符”,而是“为高频查找路径建目录卡”。