【MySQL】复合索引和覆盖索引的区别和介绍

85 阅读4分钟

@[TOC]

阅读本篇文章预计五分钟;

前言准备

我们先准备一张表和几个字段,方便介绍覆盖索引和复合索引。 创建一个user表,表中有idnameschoolage字段。

字段名字段类型
idint
namevarchar
schoolvarchar
ageint


复合索引

先来说复合索引,复合索引是一种索引,它包含多个字段,复合索引能够使一个SQL查询多个条件时也能走索引,提高查询性能。 比如,创建一个nameschoolage的复合索引: CREATE INDEX idx_name_school_age ON user(name, school, age);

查询SQL为: select * from user where name = '张三' and school = '北京大学' and age > 18 注意,在这里要注意查询条件的顺序要按照复合索引的字段顺序,要是不按照复合索引的顺序,通常情况下是不会走索引的,因为复合索引是按照最左匹配原则最左匹配原则的意思是查询条件的顺序要按照复合索引字段顺序。


为什么要说通常情况下不走索引呢,是因为MySQL的查询优化器会根据条件查询和数据分布情况选择最优的执行计划,假设,我们把schoolname的查询条件到换一下,变成: select * from user where school = '北京大学' and name = '张三' and age > 18

如果,我们条件中的school的值非常稀疏nameage的值非常密集,那么MySQL在查询时会认为使用索引能够加速查询,也会使用索引。


这里,有些同学可能会对稀疏密集这两个词有些困惑,不明白这两个词的意思,在这里要单独拿出来说一下,下面往user表中增加五条数据,做为案例数据:

idnameschoolage
1张三北京大学18
2李四北京大学18
3王五清华大学18
4赵六北京大学18
5金七清华大学18

稀疏的意思是每个不同的值出现的次数很多,比如说user表中有五条记录,name字段分别有张三、李四、王五、赵六、金七,那么我们就可以说name这个字段非常稀疏; 那么相反,密集就好理解了,比如,userschool字段的值分别只有北京大学和清华大学,那么就可以说school字段的值非常密集。


总之,MySQL的查询优化器会根据条件查询和数据分布情况选择最优的执行计划,并不是说我们不按照复合索引的字段顺序做查询条件就不会走复合索引。



覆盖索引

覆盖索引是一种索引优化手段,假设,我们想查询user表中name等于张三,获取张三schoolage字段数据,那么我们的SQL应该是: slelect school, age from user where name = '张三'

那么,为了优化这个查询SQL,我们就需要创建一个复合索引,复合索引中有nameschoolage字段: CREATE INDEX idx_name_school_age ON user(name, school, age);

当我们查询SQL时,MySQL就可以直接从索引中获取所需要的数据,不需要再回表查询数据了,这样就能大大的提高查询速度。


在这里介绍一下回表: 假设,我们创建一个复合索引,复合索引中有nameage字段: CREATE INDEX idx_name_school_age ON user(name, age);

我们这里写一个查询SQL,SQL中查询name等于张三schoolage字段值: slelect school, age from user where name = '张三'

那么在查询时,SQL语句会直接查询索引,从索引中查询到name叫做张三的数据位置,再根据位置去表中查询完整的数据,这里,根据位置去表中查询完整的数据叫做回表。



总结

覆盖索引和复合索引的区别是:覆盖索引是一种索引优化技术,而复合索引是一种索引。 使用复合索引时应该注意查询SQL条件的顺序,以及要避免回表,从而影响到查询效率。





End