mysql必知必会系列主要是针对InnoDB存储引擎进行讲解。

索引分类

索引的分类可以从不同的维度进行分类

1、按使用的数据结构划分

  • B+树索引
  • Hash索引
  • ...

2、按实际的物理存储数据构划分

  • 聚簇索引
  • 非聚簇索引(二级索引)

聚簇索引和非聚簇索引后面会着重说。

3、按索引特性划分

  • 主键索引
  • 唯一索引
  • 普通索引
  • 全文索引
  • ...

4、按字段个数划分

  • 单列索引
  • 联合索引

索引数据结构

为了接下来文章更好地讲解,这里我准备了一张user表,接下来整篇文章的示例会以这张表来讲解

CREATE TABLE `user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  `city` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Hash索引

Hash索引其实用的不多,最主要是因为最常见的存储引擎InnoDB不支持显示地创建Hash索引,只支持自适应Hash索引。虽然可以使用sql语句在InnoDB显示声明Hash索引,但是其实是不生效的

MySQL 什么情况要加索引_mysql

对name字段建立Hash索引,但是通过show index from 表名就会发现实际还是B+树

MySQL 什么情况要加索引_MySQL 什么情况要加索引_02

在存储引擎中,Memory引擎支持Hash索引。Hash索引其实有点像Java中的HashMap底层的数据结构,他也有很多的槽,存的也是键值对,键值为索引列,值为数据的这条数据的行指针,通过行指针就可以找到数据。假设现在user表用Memory存储引擎,对name字段建立Hash索引,表中插入三条数据

MySQL 什么情况要加索引_数据_03

Hash索引会对索引列name的值进行Hash计算,然后找到对应的槽下面,如下图所示

MySQL 什么情况要加索引_Hash索引_04

当遇到name字段的Hash值相同时,也就是Hash冲突,就会形成一个链表,比如有name=张三有两条数据,就会形成一个链表。之后如果要查name=李四的数据,只需要对李四进行Hash计算,找到对应的槽,遍历链表,取出name=李四对应的行指针,然后根据行指针去查找对应的数据。

Hash索引优缺点

  • hash索引只能用于等值比较,所以查询效率非常高
  • 不支持范围查询,也不支持排序,因为索引列的分布是无序的

B+树

B+树是mysql索引中用的最多的数据结构,这里先不介绍,下一节会着重介绍。