前言准备
我们先准备一张表和几个字段,方便介绍覆盖索引和复合索引。
创建一个user表,表中有id、name、school、age字段。
字段名 | 字段类型 |
id | int |
name | varchar |
school | varchar |
age | int |
复合索引
先来说复合索引,复合索引是一种索引,它包含多个字段,复合索引能够使一个SQL查询多个条件时也能走索引,提高查询性能。
比如,创建一个name、school和age的复合索引:
CREATE INDEX idx_name_school_age ON user(name, school, age);
查询SQL为:
select * from user where name = '张三' and school = '北京大学' and age > 18
注意,在这里要注意查询条件的顺序要按照复合索引的字段顺序,要是不按照复合索引的顺序,通常情况下是不会走索引的,因为复合索引是按照最左匹配原则,最左匹配原则的意思是查询条件的顺序要按照复合索引字段顺序。
为什么要说通常情况下不走索引呢,是因为mysql的查询优化器会根据条件查询和数据分布情况选择最优的执行计划,假设,我们把school和name的查询条件到换一下,变成:
select * from user where school = '北京大学' and name = '张三' and age > 18
如果,我们条件中的school的值非常稀疏,name和age的值非常密集,那么MySQL在查询时会认为使用索引能够加速查询,也会使用索引。
这里,有些同学可能会对稀疏和密集这两个词有些困惑,不明白这两个词的意思,在这里要单独拿出来说一下,下面往user表中增加五条数据,做为案例数据:
id | name | school | age |
1 | 张三 | 北京大学 | 18 |
2 | 李四 | 北京大学 | 18 |
3 | 王五 | 清华大学 | 18 |
4 | 赵六 | 北京大学 | 18 |
5 | 金七 | 清华大学 | 18 |
稀疏的意思是每个不同的值出现的次数很多,比如说user表中有五条记录,name字段分别有张三、李四、王五、赵六、金七,那么我们就可以说name这个字段非常稀疏;
那么相反,密集就好理解了,比如,user表school字段的值分别只有北京大学和清华大学,那么就可以说school字段的值非常密集。
总之,MySQL的查询优化器会根据条件查询和数据分布情况选择最优的执行计划,并不是说我们不按照复合索引的字段顺序做查询条件就不会走复合索引。
覆盖索引
覆盖索引是一种索引优化手段,假设,我们想查询user表中name等于张三,获取张三的school和age字段数据,那么我们的SQL应该是:
slelect school, age from user where name = '张三'
那么,为了优化这个查询SQL,我们就需要创建一个复合索引,复合索引中有name、school和age字段:
CREATE INDEX idx_name_school_age ON user(name, school, age);
当我们查询SQL时,MySQL就可以直接从索引中获取所需要的数据,不需要再回表查询数据了,这样就能大大的提高查询速度。
在这里介绍一下回表: 假设,我们创建一个复合索引,复合索引中有name和age字段:
CREATE INDEX idx_name_school_age ON user(name, age);
我们这里写一个查询SQL,SQL中查询name等于张三的school和age字段值:
slelect school, age from user where name = '张三'
那么在查询时,SQL语句会直接查询索引,从索引中查询到name叫做张三的数据位置,再根据位置去表中查询完整的数据,这里,根据位置去表中查询完整的数据叫做回表。
总结
覆盖索引和复合索引的区别是:覆盖索引是一种索引优化技术,而复合索引是一种索引。
使用复合索引时应该注意查询SQL条件的顺序,以及要避免回表,从而影响到查询效率。
到此这篇关于MySQL中复合索引和覆盖索引的区别详解的文章就介绍到这了,更多相关MySQL复合索引和覆盖索引内容请搜索编程客栈(www.cppcns.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.cppcns.com)!