MySQL索引?

前言

主要记录一些面试的时候关于索引的面试题,被吊打完回来发现确实有很多不够深入理解的。

什么是索引?

索引其实是一种数据结构,在查询的时候可以利用索引大大的优化MySQL查询的效率。

MySQL的话主要是有两种索引: Hash索引B+树索引, MySQL的InnoDB引擎默认使用的就是 B+树索引 。(如果后面没有重点提到Myisam引擎的话默认都是说InnoDB相关的知识)

关于B+树索引没有了解过的同学可以先看看这篇文章 MySQL的底层数据结构 。

索引的数据结构

上面有说到,索引就是大大的优化了查询的效率,那么索引是如何优化的呢,是根据什么样的数据结构做到优化的?

索引的话主要有两种数据结构: B+树Hash索引。MySQL中InnoDB默认的索引结构是 B+树 的。

为什么InnoDB采用B+树?和Hash索引比较有什么优缺点?

由于我们之前都了解过 「 MySQL的底层数据结构 」 的相关知识点,那么这里的话应该就可以很好的答上来,因为 B+树索引 的底层是一个链表,在叶子节点是有 「 顺序关系 」 的,在范围查询上不需要做到全表扫描。

Hash索引 是一种 k-v 存储数据的结构,所以在每个节点上的数据是 没有任何顺序关系 的,需要做到全表扫描。

聚簇索引和非聚簇索引

既然聊到 B+树索引 ,那 B+树索引的叶子节点 一般是存储什么东西呢?

这里涉及到了 聚簇索引非聚簇索引 的相关知识点。

聚簇索引: 一般以主键作为索引,没设置就会设立一个隐式的索引,聚簇索引的叶子节点会存放所有的数据。

非聚簇索引: 叶子节点存放的不是所有的数据,而是主键的值。

ok,那么我们来看看一般 聚簇索引 到底长什么样的:

假如存在一个学生表,里面比较简单就是一个主键的学生ID、名字、学号三个列,InnoDB默认主键为索引,假设我们啥也没设置,就一个ID作为主键,那么就是一个很明显的 聚簇索引 了如图:

学生表B+树数据结构

但假如,在这种情况下,我将学号也设为索引,那么就需要新维护一个B+树来专门作为索引来用了,如图:

非聚簇索引

这里不难看出,假如我们新增了一列作为非聚簇索引,那么就需要新增一颗 B+树 来维护新的索引结构,这就是为什么索引 优化了查询效率,但是影响了写入和删除的效率 了,因为需要多在几棵树上做操作呀!

那么聚簇索引和非聚簇索引在查询上有什么区别吗?

很好理解吧! 聚簇索引快,因为聚簇索引的叶子节点就是我们需要的整条数据,也就是学生数据,但是非聚簇索引的话是需要 「 回表 」 操作,需要查找两次,如图:

非聚簇索引的查找

  1. 查找学号为1406的学生信息。
  2. 在学号索引树里面做查找。
  3. 找到学号1406对应的主键索引ID:6。
  4. 再去聚簇索引里面查找。

这就是一个 回表 的操作。

但是,并非所有情况都需要回表操作的:

还是学生表,假如我查询的是: 「 select id from student where stu_id = 1406 」

很明显在 非聚簇索引树 找到主键ID直接返回就好了。
又名 覆盖索引

联合索引

一般什么情况下需要创建索引?创建索引一般会考虑什么?

通过上面我们知道,索引是作为 优化查询 的一种数据结构,它在优化查询的同时也会影响 写入效率

所以一般读多写少的场景就需要创建索引了。

联合索引有用过吗?在联合索引的多个字段之间的顺序是如何判断的呢( 最左前缀匹配 )?

联合索引一般需要根据业务需求来创建,where语句中使用最频繁的一列放在最左边。

因为MySQL索引查询会遵循 最左前缀匹配 的原则,在检索数据的时候从联合索引的最左边开始匹配。

所以在你创建联合索引的时候,假如还是学生表(id, stu_id, name),相当于创建了(id)、(id, stu_id)、(id, stu_id, name)三个索引,这就是最左匹配原则。

在这里最左匹配原则涉及到了数据库优化等等一系列知识,有机会再看看怎么记一下吧。

总结

简单理解一下,其实索引就类似于是书的目录,在目录里面记录了对应信息的页数,在目录找到自己需要的东西,再去对应的页里面去找到数据就好了。

都结合网上资料加上自己的一些理解,如果有影响到他人的地方,可以联系我:[email protected]

你可能感兴趣的:(MySQL索引?)