mysql之索引

全文keyword:

索引 
聚簇索引 非聚簇索引 覆盖索引 回表
B+树  哈希索引 最左匹配 联合索引 innodb myisam

什么是索引

数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。 —from维基百科

索引用来快速定位数据,避免每次访问时对数据库的每一行进行检索操作

提炼一下,索引就是一种数据结构,通过这种数据结构来实现对数据库表中数据的高效操作,其实也是一种典型的空间换时间的思想的提现。

索引及数据的组织方式

根据索引和具体数据的组织存储方式,我们可以分为聚簇索引(Clustered)和非聚簇(Non-clustered)索引

先引用网上的一张图

这张图描述的是表(拥有主键id和name字段)在id和name上的索引的两种方式。

  • 左边图片中,主键索引就是聚簇索引,可以看到此处的叶子节点和数据行存放在一起了,因为无法将数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引;接下来看辅助键索引(name字段上的索引),此处的叶子节点存放的就是该字段对应的键值以及主键id,所以当我们通过这个索引进行数据查询时,我们还需要通过主键id的聚簇索引进行再一次的查找才能定位到具体的行记录,这个过程就是回表,下面会提到怎么样通过索引覆盖的方式来避免回表,从而提高查询的效率。
  • 右边图片中,主键索引和辅助键索引并没有差异,两者的叶子节点都不存放数据行,而是通过指针的方式指向了数据存放的位置。 所以,可以看出,二者最核心的区别就是叶子节点是否包含完整的数据行。

MyISAM 和 InnoDB

  • 此两者是mysql的两种存储引擎
  • V5.1之前默认存储引擎是MyISAM;在此之后默认存储引擎是InnoDB
  • InnoDB支持事务,MyISAM不支持事务
  • 基于上面所述的聚簇索引,所以推荐InnoDB引擎使用自增主键,在没有显式设置主键时,会默认生成一个不可见的

索引覆盖

上面提到,在聚簇索引里面,如果使用辅助键索引进行数据查询时,需要进行回表操作,增加了一次查询,我们可以通过在想要查询的语句上建立联合索引来避免回表操作(待查询的语句作为索引的一部分已经保存在叶子节点上,所以不需要回表来获得想要的字段信息)。

索引的实现

首先明确一点,我们在索引及数据的组织方式中所采用的数状结构其实就是概念上的索引的一种实现方式,常见的用来实现索引的数据结构有平衡树B+数哈希.

此处我们简单粗暴地区分为树和哈希,顾名思义,二者分别是使用树和哈希表来使用索引,而我们知道这两种数据结构的特点,哈希索引的检索可以一次定位,而树的索引则需要从根节点都叶子节点才能够检索到,基于此,两者索引也有不同的优缺点及不同的应用场景,而在大部分场景下,哈希索引都是比较局限的,所以我们一般采用的是B+树索引的实现。

索引的失效及其原因

基于上面提到的索引实现,在某些场景下索引会失效,这部分内容以及索引的具体实现会另外进行剖析。

参考