MySQL 索引:让数据查询快起来的「快捷方式」
大家平时用 MySQL 查数据时,有没有遇到过这种情况:一张表存了几十万条用户数据,想查某个用户的信息,结果等了好几秒才出来?但有时候同样的表,查数据又快得像 “闪电”—— 这背后的关键,很可能就是 “索引” 在起作用。
今天就用大白话跟大家聊聊:MySQL 索引到底是啥?它为啥能让查询变快?咱们该怎么用它?
一、先搞懂:索引到底是什么?(用图书馆比喻)
其实索引一点都不复杂,你可以把它理解成图书馆里的 “图书目录”。
比如你想找一本《MySQL 入门》:
- 没有目录的话,你得从第一排书架开始,一本本翻到最后一排,运气不好可能要找半小时(这就像 MySQL “全表扫描”,逐行查数据);
- 有目录的话,你先看目录,找到 “《MySQL 入门》在计算机类 - 数据库区 - 第 3 书架第 12 层”,直接去这个位置拿书,1 分钟搞定(这就是 MySQL 用索引查数据的过程)。
对应到 MySQL 里:
- 索引不存实际的用户数据(比如用户名、手机号),只存两件事:数据的 “关键字”(比如你按 “用户 id” 查,关键字就是 id;按 “用户名” 查,关键字就是名字)和数据在硬盘上的 “地址”(就像图书的 “书架位置”);
- 查数据时,MySQL 先查索引找到 “地址”,再去地址里拿实际数据,不用扫遍整个表 —— 这就是索引能提速的核心原因。
二、为什么需要索引?(对比 “有无索引” 的差别)
咱们用实际场景感受下:假设一张user表有 100 万条数据,要查 “id=500000 的用户信息”。
1. 没有索引:全表扫描
MySQL 会从表的第 1 行开始,逐行判断 “这行的 id 是不是 500000”,直到找到目标行 —— 运气差的话,要扫完 100 万行才能找到,耗时可能要几秒甚至更久。
2. 有索引(按 id 建索引)
MySQL 直接查索引,通过 “id=500000” 这个关键字,瞬间找到对应的 “数据地址”,再去地址取数据 —— 整个过程可能只要 0.001 秒,速度差了几千倍!
简单说:索引就是为了解决 “查数据慢” 的问题,尤其表数据越多,索引的作用越明显。
三、索引怎么工作?(B + 树:最常用的 “索引结构”)
你可能听过 “B + 树索引”,别被 “树” 这个词吓到,其实它就是个 “多层目录”,咱们用按 “id” 建索引的例子来说明:
可以把 B + 树想成 3 层的目录:
- 最上层(根节点):大分类,比如 “id<100000”“100000≤id<200000”“id≥200000”;
- 中间层(分支节点):细分分类,比如 “id<100000” 下面再分 “id<50000”“50000≤id<100000”;
- 最下层(叶子节点):存实际的 “关键字 + 数据地址”,比如 “id=500000 → 地址:硬盘第 X 区第 Y 块”。
查 “id=500000” 时,MySQL 只要走 3 步:
- 根节点找 “id≥200000”;
- 分支节点找 “500000 所在的细分区间”;
- 叶子节点直接拿地址,去取数据。
不管表有 100 万还是 1 亿条数据,B + 树的层数基本都是 3-4 层,查数据的速度几乎不会变 —— 这就是它的厉害之处。
索引本质上分为主键索引和普通索引两个索引
我们直接来看索引操作
1.索引的创建
1.创建主键索引
-- 在创建表的时候,直接在字段名后指定 primary key
create table user1(id int primary key, name varchar(30));
-- 在创建表的最后,指定某列或某几列为主键索引
create table user2(id int, name varchar(30), primary key(id));
create table user3(id int, name varchar(30));
-- 创建表以后再添加主键
alter table user3 add primary key(id);
2.唯一索引的创建方式
-- 在表定义时,在某列后直接指定unique唯一属性。
create table user4(id int primary key, name varchar(30) unique);
-- 创建表时,在表的后面指定某列或某几列为unique
create table user5(id int primary key, name varchar(30), unique(name));
create table user6(id int primary key, name varchar(30));
alter table user6 add unique(name);
3.普通索引的创建
create table user8(id int primary key,
name varchar(20),
email varchar(30),
index(name) --在表的定义最后,指定某列为索引
);
create table user9(id int primary key, name varchar(20), email
varchar(30));
alter table user9 add index(name); --创建完表以后指定某列为普通索引
create table user10(id int primary key, name varchar(20), email
varchar(30));
-- 创建一个索引名为 idx_name 的索引
create index idx_name on user10(name);
2.索引的查询
第一种方法: show keys from 表名;
第二种方法: show index from 表名;
第三种方法(信息比较简略): desc 表名;
3.删除索引
第一种方法-删除主键索引: alter table 表名 drop primary key;
第二种方法-其他索引的删除: alter table 表名 drop index 索引名;
索引名就是show keys from 表名中的 Key_name 字段
mysql> alter table user10 drop index idx_name;
第三种方法方法: drop index 索引名 on 表名
mysql> drop index name on user8;
我们发现只有主键索引删除可以直接drop primary key
3.其他索引
1.复合索引
主键和唯一键都有复合主键和复合唯一键
索引同理 这里就不赘述了
删除复合键
2.全文索引
我们先来建表
我们先用普通方式来查表
我们再用全文索引方式查表
MySQL 中 EXPLAIN 的作用主要是分析 SQL 查询的执行计划,助力查询性能优化与数据库原理理解
我们发现普通查询没有用到索引 查询范围是ALL
而全文索引使用了索引 查询范围是fulltext 效率更高