没有索引时,MySQL 查数据像馆员从第一页翻到最后一页。
有索引时,像先查目录卡,再去准确定位。
没有索引
SELECT -> 从第 1 行翻到最后 1 行
有索引
SELECT -> 先查目录卡 -> 定位到记录 -> 取出目标行最常见的索引是 B-Tree 索引。你可以这样建:
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);索引不是越多越好,因为它有成本:
- 占空间
- 写入要维护
- 更新要维护
- 删除也要维护
所以索引的本质是:
用空间和写入成本,换读取速度。
复合索引尤其重要。比如:
CREATE INDEX idx_citizens_household_status
ON citizens (household_id, status);它更适合这类查询:
SELECT *
FROM citizens
WHERE household_id = 1
AND status = 'active';也常常能用于:
SELECT *
FROM citizens
WHERE household_id = 1;但未必适合只查:
SELECT *
FROM citizens
WHERE status = 'active';这就是常说的左前缀思维:复合索引更像按顺序排好的目录卡。
再看两个关键事实:
1. 唯一索引不等于主键
national_id CHAR(18) NOT NULL UNIQUE这是业务唯一号;而 citizen_id 才是表的主编号。
2. 外键关系也需要索引意识
MySQL 对外键相关列要求可高效检查,必要时会建立可用索引,但你不能因此放弃索引设计思考。真正决定查询性能的,仍然是你的访问模式。
一句话记忆:
索引不是“给字段贴加速符”,而是“为高频查找路径建目录卡”。