🥰个人主页:会编程的土豆(欢迎来访)
💎作者简介:后端学习者 ❄️个人专栏:数据结构与算法,数据库,leetcode ✨那些你一个人走过的夜路,终将化作照亮未来的光



一、索引是什么
1. 一句话定义
索引 = 给表做的「目录」。
- 有索引:常能少扫很多行
- 没索引:可能整表翻(全表扫描)
2. 为什么需要索引
表里有 100 万用户,你要查:
SELECT * FROM users WHERE phone = '13800001111';

要点:
- 索引不是让 SQL 语法变厉害
- 而是让「找数据」这条路更短
3. 在整条 SQL 链路里的位置
你发一条 SQL
→ 优化器要想:有没有合适索引?走哪个最快?
→ 执行器按计划去取数
→ 存储引擎(InnoDB)里,索引和数据真正怎么组织
二、主键索引与普通索引
1. 主键索引(最常见)
每张表通常有一个主键(如 id)。
在 InnoDB 里可以先这么理解:
- 主键像主目录
- 数据行跟着主键这套结构放着
所以:
SELECT * FROM newtable WHERE id = 3;
一般会很快——因为常常直接走主键。
2. 普通索引(二级索引)
经常按姓名查时,可以给 name 建索引:
— 概念:给 name 建目录
CREATE INDEX idx_name ON newtable(name);
查询:
SELECT * FROM newtable WHERE name = '炎龙铠甲';
直觉过程(两步)
第 2 步叫「回表」:普通索引有时要多跳一次。
3. 索引不是越多越好

先够用的原则
4. 什么样的条件更容易用上索引
比较容易
WHERE id = 3
WHERE phone = '138…'
WHERE name = '张三'
比较容易废掉或不好用(先混个脸)
WHERE age + 1 = 20 — 对列做运算
WHERE name LIKE '%铠甲' — 前模糊
WHERE name != '张三' — 不等有时也不友好
零基础先记:
等值查、条件干净,更容易走索引。
5. 自己怎么看有没有走索引
EXPLAIN SELECT * FROM newtable WHERE id = 3;
先看:
- type:访问方式粗不粗
- key:实际用了哪个索引
有用到索引时,常能看到索引名;全表扫则会比较「笨」。
三、回表
1. 普通索引怎么查(引出回表)
表 newtable:主键 id,普通索引在 name 上。
SELECT * FROM newtable WHERE name = '炎龙铠甲';
两步直觉
定义
回表 = 从「普通索引」跳回「主键那套数据」再取完整行。
像:目录上只有页码,还得翻回正文把整页看完。
2. 为什么要回表?
普通索引里通常不存整行所有字段,主要存:
- 索引列的值(如 name)
- 对应的主键(id)
你要的是 SELECT *(所有列),目录里不够,就必须回主书再拿。
四、覆盖索引
1. 一句话定义
覆盖索引 = 这次查询需要的列,索引里全有了,够用,不必再回主表。
2. 例子
只要姓名:
SELECT name FROM newtable WHERE name = '炎龙铠甲';
此时:
- 在 name 索引里已经能拿到 name
- 主键 id 通常也在索引里
- 若你要的列都被索引「盖住」→ 不用回表
像:目录上已经写了你要的信息,不用再翻正文。

3. 对比记忆
| SELECT * … WHERE name = ? | 常常要 | * 要整行,普通索引不够 |
| SELECT name … WHERE name = ? | 常常不要 | 更容易被索引覆盖 |
| SELECT * … WHERE id = ? | 一般直接拿 | 主键对着整行 |
实用提醒: 少用盲目的 SELECT *,只查需要的列,更容易吃到覆盖索引。
五、联合索引 & 最左前缀
1. 联合索引是什么
联合索引 = 一个目录同时按多列排序(例如先 name,再 age)。
不是建两个索引,而是一本合订目录。
CREATE INDEX idx_name_age ON newtable(name, age);
意思:目录按 (name, age) 这个顺序排。
2. 为什么要用联合索引?
假如你经常这样查:
WHERE name = '炎龙铠甲' AND age = 89

先记感觉:
经常一起出现在 WHERE 里的列,可以考虑做成联合索引。
3. 最左前缀(核心)
联合索引 (name, age) 可以想成:
先按 name 排成大组
└── 同一 name 里,再按 age 排
所以它最认:从左边第一列开始用。
容易用上
WHERE name = '炎龙铠甲'
WHERE name = '炎龙铠甲' AND age = 89
- 只用到最左的 name → 可以
- name + age 都用到 → 更理想
错误用法(用不好)
WHERE age = 89
只有 age,跳过了最左边的 name → 这本合订目录不好使。
像新华字典:不按拼音首字母,却按页脚小字找。
口诀:
联合索引:从左往右用;中间不能空着跳。

4. 和覆盖索引的关系
如果索引是 (name, age),你查:
SELECT name, age FROM newtable WHERE name = '炎龙铠甲';
需要的列目录里都有 → 更容易变成覆盖索引,少回表。
5. 字段顺序怎么选(实用原则)
建 (a, b, c) 时,大致想:
例子
- 常查 WHERE name = ? 或 name + age → (name, age) 合理
- 几乎只查 WHERE age = ? → 单独给 age 建索引,别指望 (name, age) 救你
六、EXPLAIN 速查(配套工具)
1. 怎么用
EXPLAIN SELECT * FROM newtable WHERE id = 3;
2. 零基础先看三列
| type | 访问方式好不好(ALL 最要警惕) |
| key | 实际用了哪个索引(NULL 很危险) |
| rows | 大概扫描多少行(越小通常越好) |
3. 口诀
EXPLAIN 先问路;type 看姿势,key 看索引用没,rows 看翻多少;遇见 ALL,心里敲锣。
七、总复习口诀
| 索引 | 表的目录,让查找更快 |
| 主键索引 | 主目录,常直接对着整行 |
| 普通索引 | 先找主键,再回表取整行 |
| 回表 | 从二级索引跳回主数据 |
| 覆盖索引 | 目录里字段已够,不用回表 |
| 联合索引 | 多列合订目录 |
| 最左前缀 | 从左往右用,不能只拿右边列 |
| EXPLAIN | 查岗:看走没走索引 |



