MySQL 索引汇总

108 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


1. MySQL 索引****

索引(index)是帮助MySQL高效获取数据的数据结构(有序)

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。

 

(1) 索引分类****

①普通索引 :普通索引允许被索引的数据列包含重复的值

②唯一索引 :索引列的值必须唯一,但允许有空值

 

③单值索引 :即一个索引只包含单个列,一个表可以有多个单列索引

④复合索引 :即一个索引包含多个列

 

(2) 索引设计原则****

①对查询频次较高,且数据量比较大的表建立索引

②组合索引挑选最常用、过滤效果最好的列的组合

③使用唯一索引,区分度越高,使用索引的效率越高

④使用短索引,构成索引的字段总长度比较短,提升索引访问的I/O效率

⑤尽可能建前缀索引,比如密码就适合建立前缀索引,因为密码几乎各不相同,前缀的标识度高,能缩短索引长度

 

(3) 版本索引优化****

MySQL5.6引入了索引下推优化,默认是开启的

 

例子:user表中(a,b,c)构成一个索引。 select * from user where a='23' and b like '%eqw%' and c like 'dasd'。

解释:

如果没有索引下推原则,则MySQL会通过a='23' 先查询出一个对应的数据。然后返回到MySQL服务端。MySQL服务端再基于两个like模糊查询来校验and查询出的数据是否符合条件。这个过程就设计到回表操作。

 

如果使用了索引下推技术,则MySQL会首先返回返回条件a='23'的数据的索引,然后根据模糊查询的条件来校验索引行数据是否符合条件,如果符合条件,则直接根据索引来定位对应的数据,如果不符合直接reject掉。因此,有了索引下推优化,可以在有like条件的情况下,减少回表的次数。

 

2. B+ Tree 索引和Hash 索引区别****

①hash索引适合等值查询,但是无法进行范围查询。

②hash索引没办法利用索引完成排序。

③hash索引不支持多列联合索引的最左匹配规则。

④如果有大量重复健值得情况下,hash索引的效率会很低,因为哈希碰撞问题。

www.cnblogs.com/dbbull/p/15…

 

3. 聚簇索引****

聚簇索引与非聚簇索引是从文件存储的角度进行划分:

聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据(InnoDB引入),在一张表上最多只能创建一个聚集索引,默认是主键(可以多列)

非聚簇索引:将数据和索引进行分开存储(MyISAM都是非聚簇索引)

image.png  

4. 回表****

 

baijiahao.baidu.com/s?id=172182…

对于主键索引和非主键索引,使用的数据结构都是 B+Tree,唯一的区别在于叶子结点中存储的内容不同:

主键索引的叶子结点存储的是一行完整的数据。

非主键索引的叶子结点存储的则是主键值。

(1) 为什么有回表****

当我们需要查询的时候:

 

如果是通过主键索引来查询数据,例如 select * from user where id=100,那么此时只需要搜索主键索引的 B+Tree 就可以找到数据。

如果是通过非主键索引来查询数据,例如 select * from user where username='javaboy',那么此时需要先搜索 username 这一列索引的 B+Tree,搜索完成后得到主键的值,然后再去搜索主键索引的 B+Tree,就可以获取到一行完整的数据。

 

对于第二种查询方式而言,一共搜索了两棵 B+Tree,第一次搜索 B+Tree 拿到主键值后再去搜索主键索引的 B+Tree,这个过程就是所谓的回表

 

(2) 不用主键索引就一定需要回表吗****

不一定

如果查询的列本身就存在于索引中,那么即使使用二级索引,一样也是不需要回表的。  

举个例子,我有如下一张表:

uname 和 address 字段组成了一个复合索引,那么此时,索引树的叶子节点中除了保存主键值,也保存了 address 和uname 的值。

查询语句  select uname, address from user where username='javaboy' 这里的返回结果在二级索引上就能提供,所以无需回表查询