mysql索引

MySQL 索引基础笔记(小白友好版)

一句话理解:索引就是书的目录。 没有目录,找内容得一页页翻(全表扫描);有了目录,直接翻到对应页(使用索引),速度飞快。


一、 什么是索引(Index)

官方定义 :一种帮助 MySQL 提高查询效率的数据结构。索引本身也就是一种数据结构。

1. 索引的优点

  • 大大加快数据的查询速度(最核心的作用)。

2. 索引的缺点

  • 耗资源:维护索引需要耗费数据库的 CPU 和内存资源。
  • 占空间:索引需要占用额外的磁盘空间。
  • 拖慢增删改 :当对表的数据进行 INSERT、UPDATE、DELETE 时,数据库不仅要改数据,还要去维护索引树,速度会受到影响。

💡 总结:索引是用"空间"和"增删改的性能",来换取"查询的速度"。


二、 索引分类

1. 按功能/物理结构分类(InnoDB 引擎)

  • a. 主键索引 (Primary Key)

    • 设定主键后,数据库会自动建立主键索引。
    • 特点 :在 InnoDB 引擎中,主键索引是聚簇索引。
    • 规则 :主键索引的列不能为空。
  • b. 普通索引 (Normal Index)

    • 即一个索引只包含单个列,一个表可以有多个普通索引。
    • 特点:没有任何唯一性限制,纯粹为了加速查询。
  • c. 唯一索引 (Unique Index)

    • 索引列的值必须唯一,但允许为空(只能有一个为空)。
  • d. 复合索引 (Composite Index)

    • 即一个索引包含多个列。
    • 原则 :使用时严格遵循最左前缀原则(下面会细说)。

2. 全文索引 (Full Text) - 补充说明

  • 作用:在文本中查找关键词(类似搜索引擎的模糊搜索),允许插入重复值和空值。
  • 适用列 :可以在 CHAR、VARCHAR、TEXT 类型列上创建。
  • ⚠️ 误区 :在mysql5.6 之前"只有 MYISAM 引擎支持全文索引"。在 MySQL 5.6 及以上版本,InnoDB 也支持全文索引了。

三、 索引的基本操作

0. 查看与删除索引

sql 复制代码
-- 查看表上的索引
SHOW INDEX FROM 表名;

-- 删除索引
DROP INDEX 索引名 ON 表名;

1. 主键索引(自动创建)

sql 复制代码
-- 创建表时指定主键,自动生成主键索引
CREATE TABLE t_user(
    id VARCHAR(20) PRIMARY KEY, 
    name VARCHAR(20)
);

2. 普通索引

sql 复制代码
-- 建表时创建(推荐用 KEY,效果同 INDEX)
CREATE TABLE t_user(
    id VARCHAR(20) PRIMARY KEY,
    name VARCHAR(20),
    KEY(name)
);

-- 建表后追加创建
CREATE INDEX nameindex ON t_user(name);

3. 唯一索引

sql 复制代码
-- 建表时创建
CREATE TABLE t_user(
    id VARCHAR(20) PRIMARY KEY,
    name VARCHAR(20),
    UNIQUE(name)
);

-- 建表后追加创建
CREATE UNIQUE INDEX name_unique_index ON t_user(name);

4. 复合索引(多列索引)

sql 复制代码
-- 建表时创建
CREATE TABLE t_user3(
    id VARCHAR(20) PRIMARY KEY,
    name VARCHAR(20),
    age VARCHAR(20),
    KEY(name, age)
);

-- 建表后追加创建
CREATE INDEX name_age_bir_index ON t_user(name, age, bir); 

四、 MySQL 索引底层原理(B+Tree)

MySQL(InnoDB)的索引底层数据结构是 B+Tree。

1. B+Tree 的特点

  • 只有叶子节点存放真实数据(或者主键值),非叶子节点只存索引键和指针。
  • 树的层级很少(通常 2~4 层),能极大地减少磁盘 I/O 次数。
  • 叶子节点之间用双向链表连接,非常适合范围查询(如 BETWEEN、>、<)。

2. B-Tree 和 B+Tree 的区别

  • B-Tree 的非叶子节点也会存数据,导致树会更高、更胖,查询效率不稳定。
  • B+Tree 数据都在叶子节点,每次查询找数据的次数(I/O 次数)是固定的,性能更稳定。

💡 补充 :每页默认存储 16KB。MySQL 在磁盘和内存之间交互数据的最小单位是"页(Page)",InnoDB 默认一页是 16KB。


五、 聚簇索引和非聚簇索引

1. 聚簇索引(Clustered Index)

  • 大白话:索引和数据"绑"在一起,找到了索引,就找到了整行数据。
  • 核心 :InnoDB 的主键索引就是聚簇索引。叶子节点里装的就是这一行所有的数据。

2. 非聚簇索引(二级索引 / 辅助索引)

  • 大白话:索引和数据"分家"了。
  • 范围:普通索引、唯一索引、复合索引都是非聚簇索引。
  • 结构 :它们的叶子节点里存的不是整行数据,而是主键的值。

⚠️ 什么是"回表"?

如果我要查 SELECT * FROM t_user WHERE name='张三'(假设 name 是普通索引):

  1. MySQL 会先在 name 的索引树里找到"张三"对应的主键 id。
  2. 然后再拿这个 id 去主键索引树 里查整行数据。
    这个"拿着主键再去查一次"的过程就叫回表。

六、 执行计划(EXPLAIN)

当你不知道 SQL 语句跑得快不快、有没有走索引时,在 SQL 前面加上 EXPLAIN 就可以查看执行计划。

sql 复制代码
EXPLAIN SELECT * FROM t_user WHERE name = '张三';

小白最需要关注的几个参数:

  • type(非常关键)

    • 表示查询的访问类型。好到坏的顺序大致是:system > const > eq_ref > ref > range > index > ALL。
    • 如果看到 ALL ,说明是全表扫描,没走索引,数据量大时极慢,必须优化。
  • key

    • 实际使用的索引名称。如果为 NULL,说明没有使用索引。
  • rows

    • MySQL 预估要扫描多少行数据才能找到结果。越少越好。
  • Extra(额外信息)

    • 如果看到 Using index:说明用了"覆盖索引",性能极好(不需要回表)。
    • 如果看到 Using filesort:说明在内存或磁盘里做了额外排序,可能需要优化。
    • 如果看到 Using temporary:说明使用了临时表,性能较差。
相关推荐
普通人66 小时前
WebGL与WebGPU入门指南
开发语言·webgl·1024程序员节
星恒随风16 小时前
MySQL 从零入门(五):MySQL 内置函数详解——日期、字符串、数学函数与实战案例
linux·数据库·笔记·sql·mysql
2603_9696948519 小时前
【JavaWeb学习记录】MyBatis核心知识点与实战笔记:从入门到动态SQL
笔记·sql·学习·mysql·mybatis·javaweb·学习方法
数据技术说20 小时前
在 KES AI 数据库上搭一条 NL2SQL 链路:语义、召回、权限各放哪
人工智能·sql·代码规范
猫猫不是喵喵.1 天前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
codeejun1 天前
每日一Go·MySQL-14、慢 SQL 产生原因全解
sql·mysql·golang
新*2 天前
Elasticsearch 7.17 的 SQL 到底能查到什么?一次踩坑记录
后端·sql·elasticsearch·查询
这个DBA有点耶3 天前
库内计算推理:一条SQL背后的算子融合,和外挂方案差了几次网络往返
数据库·人工智能·sql
Decay__3 天前
01_SQLServer 体系架构全解 —— 实例进程、关系引擎、SQLOS 与事务日志深入
运维·数据库·sql·mysql·架构
瑞雪兆丰年兮3 天前
JavaWeb-day07-MySQL(DQL&多表设计)
java·开发语言·数据库·sql·mysql·javaweb·web