MySQL之索引

260 阅读3分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

什么是索引?简单地说,索引是数据的目录,便于存储引擎快速定位数据。

索引有多个分类标准,下面对常见的几种分类进行说明。

按数据结构来分

可以分为B+树索引,哈希索引等。

1. B+树

B+树是一种多路平衡查找树,查找效率为O(logdN)O(logdN)O(log_dN)O(logdN),其中d为B+树的度,表示节点允许的最大子节点个数。其特点为:

  1. 只在叶子节点存储数据,非叶子节点只存储索引值。这样存储的好处是非叶子节点的子节点更多,树高越小,从而使得磁盘IO的次数更少(千万级别树高3-4)。
  2. 所有叶子节点形成有序链表,范围查询效率高

2. 哈希索引

哈希索引通过哈希函数得到索引字段的哈希值(也就是该条数据的存储位置),在等值查询时可以实现O(1)O(1)的时间复杂度。但由于哈希函数并不具备单调性,所有哈希索引范围查询效率低下,而且无法实现排序操作。在索引字段存在大量重复时,频繁的哈希冲突也会大大降低哈希索引的效率。因此,哈希索引只有在某些特定的情况下(等值查询、索引字段重复少)适用。

按物理存储来分

1. 聚簇索引

聚簇索引中聚簇的含义是索引值与完整数据是“聚在一起”的,二者的物理存储位置是紧挨在一起。

聚簇索引的叶子节点存储完整表数据,全表数据就存储在聚簇索引

聚簇索引默认在主键上建立;如果没有主键,在第一个唯一索引上建立;如果都没有,InnoDB会自动生成一个隐式自增ID列并在此列上建立索引。

2. 二级索引

与聚簇索引相对,二级索引的索引值与完整数据的物理存储是分离的。

二级索引叶子节点存储的是聚集索引值,如果查询的字段没有被二级索引覆盖,会进行回表。回表指的是用叶子节点的聚集索引值去聚集索引上查找数据,也就是说,为了拿到需要的数据,需要在分别在二级索引和聚集索引各自进行一次查找,因而效率较低。

覆盖索引可以避免回表,此时explain中的extra字段为using index。所谓的覆盖索引指的是查询的字段是索引字段的子集,因为索引上就覆盖了需要的字段,所以没有必要到聚集索引上再进行一次查找。

按字段的特性

1. 主键索引

顾名思义,主键索引是建立在主键上的索引。

2. 唯一索引

顾名思义,索引字段是具有唯一性约束的字段。

3. 前缀索引

对于BLOB,TEXT,或者很长的VARCHAR类型的列,处于性能的考虑,MySQL不允许索引这些列的完整长度,只能在这些字段的前缀上建立索引。

4. 普通索引

不属于上述3种的索引。

按字段的个数

1. 单列索引

顾名思义,索引字段只有一个。

2. 联合索引

顾名思义,索引字段有多个。