MySQL索引分类
概述
本文主要介绍MySQL数据库的索引分类。由于不同的分类角度导致容易混淆。
按数据结构划分
-
hash索引
MySQL并没有显式支持Hash索引,而是作为内部的一种优化。具体在Innodb存储引擎里,会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,就为之建立hash索引。因此,在MySQL的Innodb里,对于热点的数据会自动生成Hash索引。这种hash索引,根据其使用的场景特点,也叫自适应Hash索引。
-
B+树索引
这个是MySQL索引的基本实现方式。Innodb、MyISAM的索引都是通过B+树实现的。
按索引字段个数划分
-
单值索引
仅包含一个字段值得索引,称为单值索引。
-
复核索引
包含多个字段构成的索引,成为复核索引。复合索引的索引的数据顺序跟字段的顺序相关,包含多个值的索引中,如果当前面字段的值重复时,将会按照其后面的值进行排序。
如果查询条件中字段包含了复核索引中的字段,优化器也会按照索引字段顺序进行解析。单如果是不连续的则无法完全利用索引。比如建立(a,b,c)的复核索引,如果查找条件为(a,c),则只能利用a的索引。
按是否是主键划分
-
主键索引
MySQL中是根据主键来组织数据的,所以每张表都必须有主键索引,主键索引只能有一个,不能为null同时必须保证唯一性。建表时如果没有指定主键索引,则会自动生成一个隐藏的字段作为主键索引。
-
辅助索引/二级索引
如果不是主键索引,则就可以称之为非主键索引,又可以称之为辅助索引或者二级索引。主键索引的叶子节点存储了完整的数据行,而非主键索引的叶子节点存储的则是主键索引值。
通过非主键索引查询数据时,会先查找到主键索引值,然后再到主键索引上去查找对应的数据。这也是不建议主键太长的原因,因为所有辅助索引都会存储主键。
索引是否包括返回值
-
覆盖索引
在这里假设我们有张表user,具有三列:ID,age,name,create_time,id是主键,(age,create_time,,name)建立辅助索引。
执行如下sql语句
select name from user where age>2 order by create_time desc。
正常的话,查询分两步:
1 按照辅助索引,查找到记录的主键
2 按照主键主键索引里查找记录,返回name。
但实际上,我们可以看到,辅助索引节点是按照age,create_time,name建立的,索引信息里完全包含我们所要的信息,如果能从辅助索引里返回name信息,则第二步是完全没有必要的,可以极大提升查询速度。
按照这种思想Innodb里针对使用辅助索引的查询场景做了优化,叫覆盖索引。
索引与数据的存储关联性
-
聚簇索引
Innodb中的主键索引(B+树索引)结构中,非叶子节点存储的是索引指针,叶子节点存储的是既有索引也有整行数据。索引和数据是存储在一起的,是典型的聚簇索引。
-
非聚簇索引
innodb中的辅助索引结构中,叶子节点存储的是主键索引值,并没有完整数据,所以为非聚簇索引。
MyISAM中索引和数据文件分开存储,B+Tree的叶子节点存储的是数据存放的地址,而不是具体的数据,是典型的非聚簇索引;换言之,数据可以在磁盘上随便找地方存,索引也可以在磁盘上随便找地方存,只要叶子节点记录对了数据存放地址就行。因此,索引存储顺序和数据存储关系毫无关联,是典型的非聚簇索引。
其他分类
- 全文索引
- 唯一索引:索引唯一。