MySQL 系统学习 第四阶段:MySQL 高级 第一节:索引(Index)

一、为什么需要索引?

先看一个问题。

假设用户表:

复制代码
复制代码
CREATE TABLE user(
    id BIGINT,
    username VARCHAR(50),
    age INT
);

数据:

复制代码
复制代码
id    username    age

1     Tom         20
2     Jack        25
3     Lucy        18
...
10000000  Mike    30

现在执行:

复制代码
复制代码
SELECT *
FROM user
WHERE username='Tom';

没有索引时

MySQL 怎么查?

只能:

复制代码
复制代码
第一条
 ↓
第二条
 ↓
第三条
 ↓
...
 ↓
1000万条

这种方式叫:

全表扫描(Full Table Scan)

时间复杂度:

复制代码
复制代码
O(n)

数据越多:

越慢。


有索引时

例如:

给 username 创建索引:

复制代码
复制代码
CREATE INDEX idx_username
ON user(username);

MySQL 会建立类似:

复制代码
复制代码
索引结构

Tom
 |
位置
 |
数据行

查询:

复制代码
复制代码
WHERE username='Tom'

可以快速定位。

时间复杂度:

复制代码
复制代码
O(log n)

二、什么是索引?

定义:

索引是数据库为了提高查询效率而创建的一种数据结构。

简单理解:

索引 = 数据目录。


现实例子:

没有目录的书:

复制代码
复制代码
找 MySQL章节

翻第一页
翻第二页
...
翻500页

有目录:

复制代码
复制代码
目录

MySQL
  ↓
第300页

快速定位。

数据库索引也是类似思想。


三、MySQL 常见索引类型

1. 普通索引(普通查询)

语法:

复制代码
复制代码
CREATE INDEX idx_name
ON user(name);

作用:

提高查询速度。


2. 唯一索引

保证数据唯一。

例如:

手机号:

复制代码
复制代码
CREATE UNIQUE INDEX idx_phone
ON user(phone);

保证:

复制代码
复制代码
13800000001

不能重复。


3. 主键索引

创建主键:

复制代码
复制代码
PRIMARY KEY(id)

MySQL 自动创建索引。

例如:

复制代码
复制代码
id BIGINT PRIMARY KEY

4. 联合索引 ⭐⭐⭐⭐⭐

多个字段组成索引。

例如:

复制代码
复制代码
CREATE INDEX idx_name_age
ON user(name, age);

表示:

同时根据:

复制代码
复制代码
name + age

建立索引。


四、索引的数据结构

MySQL 常用:

B+Tree

这是重点。

为什么不用:

  • 数组?
  • 链表?
  • 二叉树?

而选择:

B+Tree?


1. 数组

查询:

快:

复制代码
复制代码
O(1)

但是:

插入删除慢。


2. 链表

查询:

慢:

复制代码
复制代码
O(n)

3. 二叉树

如果数据:

复制代码
复制代码
1
 \
  2
   \
    3
     \
      4

会退化成链表。


4. B+Tree

结构:

复制代码
复制代码
              50
          /        \
       20            80
     /   \          /   \
   10    30       60    90

数据存储在叶子节点

特点:

  • 高度低
  • 查询快
  • 适合磁盘
  • 范围查询优秀

所以 MySQL InnoDB 使用 B+Tree。


五、索引创建和删除

创建

复制代码
复制代码
CREATE INDEX idx_user_name
ON user(username);

查看索引

复制代码
复制代码
SHOW INDEX FROM user;

删除索引

复制代码
复制代码
DROP INDEX idx_user_name
ON user;

六、什么时候应该创建索引?

适合:

1. 经常查询字段

例如:

复制代码
复制代码
WHERE username='Tom'

2. 经常排序

例如:

复制代码
复制代码
ORDER BY create_time DESC

3. 经常关联

例如:

复制代码
复制代码
JOIN user
ON order.user_id=user.id

4. 外键字段

例如:

复制代码
复制代码
order.user_id

七、索引是不是越多越好?

不是。

这是面试高频问题。

原因:


① 占用空间

索引也是数据。

例如:

复制代码
复制代码
10GB数据

+
多个索引

可能增加几GB

② 降低写入速度

INSERT:

原来:

复制代码
复制代码
写数据

有索引:

复制代码
复制代码
写数据
+
更新索引

UPDATE:

修改字段:

可能需要更新索引。


DELETE:

删除数据:

同时删除索引记录。


所以:

索引提高查询速度,但是降低写入性能。


八、本节总结

内容 说明
索引 提高查询速度的数据结构
无索引 全表扫描
有索引 快速定位
MySQL索引结构 B+Tree
主键 自动创建索引
唯一索引 保证唯一
联合索引 多字段索引
索引缺点 占空间、降低写性能

🎯 本节核心一句话:

索引就是数据库的数据目录,通过空间换时间,让查询从扫描大量数据变成快速定位数据。

相关推荐
kkkkkkkkkk_Z16 分钟前
新手自学嵌入式 | 学习日记:Linux驱动复习之系统移植(U-Boot篇)
linux·运维·学习
Rabitebla19 分钟前
【系统性学习笔记】Linux 权限篇(二):文件属性、权限修改与目录权限的底层逻辑
linux·c++·笔记·学习·算法
钱栈up30 分钟前
前端改了三页、后端也动了,用户说「完全没变化」——我在 116 库上找到的三个真凶
css·数据库
BBmmo30 分钟前
MySQL 里大小写不同的邮箱,为什么会撞上唯一索引?
mysql
这个DBA有点耶43 分钟前
索引建了查询却更慢——优化器选错索引与Index Merge的隐藏代价
数据库·架构·代码规范
云贝贝贝1 小时前
删了却没变小:PostgreSQL 死元组与表膨胀排查
数据库·postgresql
依晨照旧1 小时前
Langfuse 打爆两台机器:一条分位数 SQL,在 400G 表上扫了 8 分钟
数据库
专注仿真1 小时前
从「能跑通」到「能交付」:一套可直接落地的电商用户行为分析平台(Python + SQLite/MySQL + Streamlit 全栈源码与部署文档)
python·mysql·sqlite
fanged2 小时前
嵌入式架构学习6--ZSWatch(TODO)
学习
笃行3502 小时前
列存储这条线,我顺着 KingbaseES 的文档摸了一遍
数据库