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:说明使用了临时表,性能较差。
相关推荐
蓝祁子yoky1 小时前
Qt学习日记 Day8:事件系统
1024程序员节
xianghongtao01161 小时前
04_ToM2Vec_解读报告
1024程序员节
夕除1 小时前
redis--IO 内核
1024程序员节
灵境(虚幻知音)1 小时前
华为超节点系统对军事体系仿真分布式计算的需求影响与技术路线变革研究
1024程序员节
Oiiouui1 小时前
针对Godot-GridGame(网格游戏)的DI注入+RefCounted数据驱动信号流架构设计的研究(全程开源)
游戏·游戏引擎·godot·1024程序员节
坤坤子吖1 小时前
C++继承:友元、静态成员、多继承与组合
开发语言·c++·笔记·学习·1024程序员节
科学熊1 小时前
OBS Studio 新手入门
1024程序员节
贵州诚鑫致达科技有限公司1 小时前
PHP两个9.2分RCE漏洞,速查版本
服务器·php·1024程序员节
漫天转悠1 小时前
Vue3白屏排查实录-Transition与多根模板
vue.js·1024程序员节