TDSQL MySQL的索引分类问题一直让人头疼,几乎全部的资料都会给你列一个长长的清单,给你介绍什么主键索引、单值索引,覆盖索引,自适应哈希索引,全文索引,聚簇索引,非聚簇索引等……给人的感受就是云里雾里,好像MySQL索引的实现方式有不少种,可是都没有一个清晰的分类。因此本人尝试总结了一下如何给MySQL的索引类型分类,便于你们记忆,因为MySQL中支持多种存储引擎,在不一样的存储引擎中实现略微有所差距,下文中若是没有特殊声明,默认指的都是InnoDB存储引擎。sql
索引从不一样维度划分能够有不少种名称,可是须要明确一个问题——索引的本质是一种数据结构,其余索引的划分则是针对实际应用而言。数据结构
1、根据底层数据结构划分工具
索引是提升查询效率的数据结构,而可以提升查询效率的数据结构有不少,如二叉搜索树,红黑树,跳表,哈希表(散列表)等,而MySQL中用到了B+Tree和散列表(Hash表)做为索引的底层数据结构(其实也用到了跳表实现全文索引,但这不是重要考点,因此能够忽略)。性能
- hash索引
MySQL并无显式支持Hash索引,而是做为内部的一种优化。具体在Innodb存储引擎里,会监控对表上二级索引的查找,若是发现某二级索引被频繁访问,二级索引成为热数据,就为之创建hash索引。所以,在MySQL的Innodb里,对于热点的数据会自动生成Hash索引。这种hash索引,根据其使用的场景特色,也叫自适应Hash索引。优化
- B+树索引
这个是MySQL索引的基本实现方式。除了全文索引、hash索引,Innodb、MyISAM的索引都是经过B+树实现的。url
2、根据索引字段个数划分.net
为了能应对不一样的数据检索需求,索引既能够仅包含一个字段,也能够同时包含多个字段。单个字段组成的索引能够称为单值索引,不然称之为复合索引,也称为组合索引或多值索引。指针
这个很好理解,假如咱们有一张表,有三个属性,分别是 id,age 和 name 。假如在id上创建索引,那这就是单值索引;若是在 name 和 age 上创建索引,那这就是复合索引。blog
复合索引的索引的数据顺序跟字段的顺序相关,包含多个值的索引中,若是当前面字段的值重复时,将会按照其后面的值进行排序。排序
使用覆盖索引的前提是字段长度比较短,对于值长度较长的字段则不适合使用覆盖索引,缘由有不少,好比索引通常存储在内存中,若是占用空间较大,则可能会从磁盘中加载,影响性能。
3、根据是不是在主键上创建的索引进行划分
- 主键索引
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里针对使用辅助索引的查询场景作了优化,叫覆盖索引(在这里小声吐槽一下,不知道业界起这种名词干吗,太容易引发歧义了,叫个索引覆盖查询不是更好吗)。
4、根据数据与索引的存储关联性划分
根据数据与索引的存储关联性,能够分为聚簇索引和非聚簇索引(也叫汇集索引和非汇集索引)。聚簇索引也叫簇类索引,是一种对磁盘上实际数据从新组织以按指定的一个或多个列的值排序。整个简洁的说法,这俩的区别就是索引的存储顺序和数据的存储顺序是不是关系的,有关就是聚簇索引,无关就是非聚簇索引。具体实现方式根据索引的数据结构不一样会有所不一样。下面以B+树实现的索引为例,举例来讲明聚簇索引和非聚簇索引。
- 聚簇索引
Innodb的主键索引,非叶子节点存储的是索引指针,叶子节点存储的是既有索引也有数据,是典型的聚簇索引(这里能够发现,索引和数据的存储顺序是强相关的。所以是典型的聚簇索引),如图:
- 非聚簇索引
MyISAM中索引和数据文件分开存储,B+Tree的叶子节点存储的是数据存放的地址,而不是具体的数据,是典型的非聚簇索引;换言之,数据能够在磁盘上随便找地方存,索引也能够在磁盘上随便找地方存,只要叶子节点记录对了数据存放地址就行。所以,索引存储顺序和数据存储关系毫无关联,是典型的非聚簇索引,另外Inndob里的辅助索引也是非聚簇索引。
5、其余分类
- 惟一索引
顾名思义,不容许具备索引值相同的行,从而禁止重复的索引或键值。系统在建立该索引时检查是否有重复的键值,并在每次使用 INSERT 或 UPDATE 语句添加数据时进行检查, 若是有重复的值,则会操做失败,抛出异常。
须要注意的是,主键索引必定是惟一索引,而惟一索引不必定是主键索引。惟一索引能够理解为仅仅是将索引设置一个惟一性的属性。
- 全文索引
在MySQL 5.6版本之前,只有MyISAM存储引擎支持全文引擎。在5.6版本中,InnoDB加入了对全文索引的支持,可是不支持中文全文索引.在5.7.6版本,MySQL内置了ngram全文解析器,用来支持亚洲语种的分词。主要用来利用关键词查询文本,不是MySQL的主要面向场景,使用较少,这里就不展开讨论了。
6、总结
最后总结一张脑图方便记忆:
本文由博客群发一文多发等运营工具平台 OpenWrite 发布