目录
1. 创建索引
1.1 自动创建索引
1.2 手动创建索引
1.2.1 主键索引
1.2.2 唯一索引
1.2.3 普通索引
2. 查看索引
3. 删除索引
3.1 删除主键索引
3.2 删除普通索引
4. 查看执行计划
4.1 不加条件,查询所有
4.2 使用主键查询
4.3 子查询中使用索引
4.4 使用普通索引
4.5 使用复合索引
5. 创建索引的注意事项
1. 创建索引
1.1 自动创建索引
- 当我们为一张表添加主键约束(Primary Key),外键约束(Foreign Key),唯一约束(Unique)时,MySQL会为对应的列创建一个索引
- 如果不指定任何约束,MySQL会自动为每一列生成一个索引并用 ROW_ID 进行标识
1.2 手动创建索引
1.2.1 主键索引
方式一:建表的时候创建主键
CREATE TABLE t_test_pk1(
student_id BIGINT PRIMARY KEY,
student_name VARCHAR(20)
);
查看表结构:
方式二:创建表时单独指定主键列
CREATE TABLE t_test_pk2(
student_id BIGINT ,
student_name VARCHAR(20),
PRIMARY KEY(student_id)
);
方式三:修改表中的列为主键
CREATE TABLE t_test_pk3(
student_id BIGINT ,
student_name VARCHAR(20)
);ALTER TABLE t_test_pk3 ADD PRIMARY KEY(student_id);
ALTER TABLE t_test_pk3 MODIFY student_id BIGINT auto_increment;
先指定 student_id 列为主键,然后再把主键列设置为自增
1.2.2 唯一索引
# ⽅式⼀,创建表时创建唯⼀键create table t_test_uk (id bigint primary key auto_increment,name varchar ( 20 ) unique);# ⽅式⼆,创建表时单独指定唯⼀列create table t_test_uk1 (id bigint primary key auto_increment,name varchar ( 20 ),unique (name));# ⽅式三,修改表中的列为唯⼀索引create table t_test_uk2 (id bigint primary key auto_increment,name varchar ( 20 ));alter table t_test_uk2 add unique (name);
1.2.3 普通索引
创建的时机:
1.创建表的时候,明确的知道某些列频繁查询,就创建好(当表中数据过少时,全表扫描可能效率比索引高)
2.随着业务的不断发展,在版本迭代的过程中添加索引
方式一:创建表时指定索引列
CREATE TABLE t_test_index1(
id BIGINT PRIMARY KEY auto_increment,
student_name VARCHAR(20),
sno VARCHAR(10),
class_id BIGINT,
INDEX(sno,class_id)
);
方式二:修改表中的列为复合索引
create table t_test_index2(
id bigint PRIMARY KEY auto_increment,
name VARCHAR(20),
sno VARCHAR(10),
class_id bigint
);alter table t_test_index2 add index(sno,class_id);
方式三:单独创建索引并指定索引名
create table t_test_index3(
id bigint primary key auto_increment,
name varchar(20),
sno varchar(10),
class_id bigint
);
一般来说,推荐使用方式三创建索引。
原因:
对比一下使用方式一和方式二创建索引,和方式三创建索引的创建效果:
方式一:
方式二:
方式三:
方式一与方式二的创建效果相同:索引名都是以首个字段名来命名
方式三使用自定义的方式来为索引命名,当查看该索引对应哪个字段的时候就能够一目了然
2. 查看索引
方式一:show keys from 表名
执行效果:
方式二:show index from 表名
执行效果:
方式三(查看简要信息):desc 表名
执行效果:
3. 删除索引
3.1 删除主键索引
现有一个数据库,包含一个主键索引,两个普通索引:
CREATE TABLE t_index(
id BIGINT PRIMARY KEY auto_increment,
name VARCHAR(20),
sno VARCHAR(10),
class_id BIGINT
);
create index t_index_sno_name on t_index(sno,name);
每个表的主键都是唯一的,当主键被删除时,主键索引也就被删除了。因此删除主键索引,其实就是删除主键:
alter table 表名 drop primary key;
alter table t_index drop primary key;
直接删除主键,此时MySQL会报错:
如果出现由于自增列的报错,首先要删除该列的自增列属性,再删除该主键:
alter table t_index modify id bigint;
alter table t_index drop primary key;
此时再查看表的索引:
主键索引已被删除
3.2 删除普通索引
删除普通索引不需要像删除主键索引一样(去掉列的自增属性),直接删除即可:
alter table t_index drop index 列名;
alter table t_index drop index t_index_sno_name;
4. 查看执行计划
怎么去查看自己写的SQL走没走索引?
需要使用一个操作,查看执行计划:explain
现有一个表:
使用SQL语句,查看执行计划:
4.1 不加条件,查询所有
explain select*from student;
4.2 使用主键查询
explain select * from student where student_id=1;
4.3 子查询中使用索引
explain select * from student where student_id=(select student_id from student where student_id=1);
关于执行计划中的type属性:
4.4 使用普通索引
explain select*from student where sn=09982;
对sn创建的两个普通索引:
4.5 使用复合索引
回表查询的情况:
当使用复合索引时,查询其中一个列:
使用sno列来查询name列:
为什么是覆盖索引:
创建索引idx_student_sn_name的同时,创建了一个索引树。
而sno和name都在该索引树内,使用sno列来查询name列时不需要再进行全表扫描,因此使用了覆盖索引。
前后对调,使用name列查询sno列:
当前后对调,此时就不止使用了覆盖索引,还使用了回表查询。
原因:
当创建一个联合索引(复合索引),在使用时,需要满足最左匹配原则。
最左匹配原则:
查询条件必须从索引的最左列开始匹配,且按顺序依次使用联合索引中的列,才能有效利用索引。
当直接使用name去查,是跳过了左侧的sn的.不满足最左匹配原则,就没有走索引。
因此用到了回表查询。
如果没有跳过左侧的列,则不会发生回表查询。
使用复合索引查询两个列:
关于Extra列:
5. 创建索引的注意事项
- 索引应该创建在高频查询的列上
- 索引需要占用额外的存储空间
- 对表进行插入、更新和删除操作时,同时也会修改索引树,可能会影响性能
- 创建过多或不合理的索引会导致性能下降,需要谨慎选择和规划索引
完
如果哪里有疑问的话欢迎来评论区指出和讨论,如果觉得文章有价值的话就请给我点个关注还有免费的收藏和赞吧,谢谢大家