MySQL 索引(Index)系统讲解

MySQL 中的索引 本质上是一种用于加速数据检索的数据结构 。理解索引,核心抓住三点:是什么、怎么用、什么时候会失效。


一、索引是什么 & 为什么快

索引类似书的目录:

  • 不用从头到尾扫描(全表扫描)
  • 通过有序结构,快速定位数据行

在 InnoDB 中,索引的底层实现是 B+Tree。

为什么是 B+Tree?

  • 树高度低(通常 2~4 层)
  • 叶子节点有序 + 双向链表
  • 范围查询效率极高
  • 适合磁盘 IO(一次 IO 读一个页)

二、MySQL 索引的分类(按逻辑)

1. 主键索引(PRIMARY KEY)

  • 表中唯一
  • 不允许 NULL
  • InnoDB 中是聚簇索引
sql 复制代码
PRIMARY KEY (id)

数据本身存放在主键 B+Tree 的叶子节点中


2. 普通索引(INDEX)

  • 仅用于加速查询
  • 可重复、可为 NULL
sql 复制代码
CREATE INDEX idx_name ON user(name);

3. 唯一索引(UNIQUE)

  • 值必须唯一(NULL 除外)
sql 复制代码
CREATE UNIQUE INDEX uk_email ON user(email);

4. 联合索引(复合索引)

  • 多个字段组成
  • 最左前缀原则
sql 复制代码
CREATE INDEX idx_abc ON t(a, b, c);

✅ 能用索引的情况:

  • a
  • a, b
  • a, b, c

❌ 不能直接用:

  • b
  • b, c

5. 全文索引(FULLTEXT)

  • 用于文本搜索(MATCH ... AGAINST)
  • 常用于文章、评论
sql 复制代码
FULLTEXT(title, content)

三、聚簇索引 vs 非聚簇索引(重点)

🔹 聚簇索引(Clustered Index)

  • 主键索引
  • 叶子节点 = 整行数据
  • 一张表只能有一个

🔹 二级索引(辅助索引)

  • 叶子节点存的是:主键值

  • 查询流程:

    1. 先走二级索引
    2. 拿到主键
    3. 再回表查数据(回表)

覆盖索引可以避免回表


四、覆盖索引(非常重要)

sql 复制代码
SELECT name FROM user WHERE name = 'Tom';
  • name 字段有索引
  • 查询字段 全在索引中
  • Extra: Using index

✅ 性能最好


五、索引什么时候会失效(高频面试)

❌ 以下情况索引可能失效:

  1. 最左前缀被破坏
sql 复制代码
WHERE b = 2 AND c = 3
  1. 对索引列使用函数
sql 复制代码
WHERE DATE(create_time) = '2026-01-01'
  1. 隐式类型转换
sql 复制代码
WHERE phone = 13800138000  -- phone 是 varchar
  1. LIKE '%xxx'
sql 复制代码
LIKE '%abc'
  1. OR 条件一边没索引
sql 复制代码
WHERE a = 1 OR b = 2

六、如何判断索引是否生效

1. EXPLAIN

sql 复制代码
EXPLAIN SELECT * FROM user WHERE email = 'a@b.com';

重点字段:

  • type(性能从好到差)
    const > ref > range > index > ALL

  • key:使用的索引

  • rows:扫描行数

  • Extra:

    • Using index(覆盖索引)
    • Using where
    • Using filesort(危险)

七、索引设计原则(实战)

✅ 该建索引

  • 高频 WHERE
  • 高频 JOIN
  • 高频 ORDER BY
  • 区分度高的字段

❌ 不建议建索引

  • 更新极其频繁的字段
  • 区分度很低(如性别)
  • 小表(数据量 < 1w)

联合索引优于多个单列索引


八、面试一句话总结

MySQL InnoDB 使用 B+Tree 作为索引结构,主键索引是聚簇索引,数据行存储在主键索引的叶子节点中,普通索引需要回表;合理使用联合索引、覆盖索引,并遵循最左前缀原则,才能发挥索引的最大性能。


相关推荐
超级新零售15 分钟前
零售 SaaS 与本地部署,技术责任边界究竟怎么分?
数据库·零售
考虑考虑33 分钟前
瀚高数据库
数据库·后端·postgresql
dishugj1 小时前
oracle日志切换三条命令区别
数据库
Patrick在香港1 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
悟道书生1 小时前
(一)Navicate为什么转存结构和数据只转存表而不包含建库?
数据库·oracle
赤龙ERP2 小时前
ERP周报:连接器开闸、国产GPU进场与智能工厂253家
数据库·人工智能·大模型·rpa·erp·企业数字化·builderpattern
lusklusklusk2 小时前
SQL Server补丁版本号为什么“日期新反而版本低”?——GDR、CU、CU+GDR 版本号规则与升级路径详解
数据库
key_3_feng2 小时前
评估与对齐:Agent 自我进化的护栏
前端·数据库·agent
TangGeeA2 小时前
数据库、SQL 与 DB AI
数据库·人工智能·sql
IvorySQL2 小时前
开源数据库进校园| 11 月 3 日,IvorySQL 校园行走进浙大宁波校区:从 PostgreSQL 扩展生态到 AI 实战
数据库·postgresql·开源