MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

MySQL索引方面的面试题

2025-02-14 23:28 huorong 精选文章 2 ℃ 0 评论

1. B+Tree作为数据库索引的优势在哪里?

这个问题要从B+Tree的演变过程来分析。

二叉树:二叉树就是我们大家熟知的二分查找法,这个在一定的程度上可以提高我们查询数据的速度。

但是在某些极端的情况下(例如要查询值再二叉树的尾部的时候),查询数的会退化为O(n),这个和全表扫描的操作基本一致。

出现这个情况的原因是这个二叉树,它不是平衡的。于是为了解决这个问题,就出现了平衡二叉树。

平衡二叉树:相对于二叉树,它修复了二叉树不平和的缺点。它是一个左右平和的二叉树,它的左右两边的叶子节点的高度差绝对值不会大于1。不会出现查询速度退化为O(n)的情况。

但是它也有一些缺点,因为它的每一个父节点最多只能有两个叶子节点,左右各一个。所以树会很高、很瘦,树的层级很深。这样就导致了每次查询数据的时候,增加了磁盘I/O的交互次数。

而每加深一层树都会增加一个磁盘的I/O,磁盘I/O每次都要有磁头的寻道时间,比较消耗性能,所以在性能上也有待提升。于是就出现了多路平衡查找树。

多路平衡查找树:也就是B-Tree,相比平衡二叉树,它是多路的,这个多路体现在一个父节点下面可以有多个叶子节点,而不是想平衡二叉树那样,每一个父节点只能有左右两个子节点。

此时的多路平衡查找树每一个节点都会存储真实的数据,当查找数据的时候,如果在某个节点查询到了目标的数据,就返回结果,并且停止搜索,也就是说查找数据的时候,不一定要遍历到树的最底层的节点。

这样就存在一个潜在的问题:查询数据的效率不稳定,有点很快就返回结果,有的需要向树下多查询几次才会返回结果。从软件设计的角度上来看这种不稳定性是不能接受的。

另外一个问题就是,因为多路平衡查找树的每一个节点都存储了所有的数据,导致了同一个page页(默认大小是16KB)中能够存储的数据行数就变少了,这样就变向的导致了树的高度会相对高一些,

所以查询数据的时候,磁盘的I/O也就会有相应的增加。为了解决这个问题,MySQL对这个多路平衡查找树做了升级,也就是我们经常说的加强版的多路平衡查找树B+Tree。

加强版的多路平衡查找树:也就是B+Tree,相对比B-Tree,B+Tree只有在叶子节点才会存储数据,非叶子节点只存储关键字。并且在也子节点之间有指针指向下一个也只节点的物理地址。

这样保证的数据的查询效率的稳定性,只有到叶子节点才能查询到所需要的数据,不会出现想B-Tree那样查询数据效率的随机性。因为在非叶子节点上不存储数据,所以在一个page页中,可以存储

更多的数据行,这样的树会更矮、更胖,查询数据的时候磁盘I/O会更少一些。因为叶子节点上有指针存在,所以在范围查找上,效率也不会低。

综上所述:B+Tree是比较适合做数据库索引。

2. 建立联合索引时为什么要关注列的排列顺序?

因为索引在创建的时候,是根据定义的列的顺序,根据列中的值来依次排列后存储的。

在比较的时候,会先根据指定的第一列的值来排序,在第一列值相同情况下在根据第二列的值来排序。

联合索引创建的时候,通常根据下面的顺序来定义:

经常使用的 > 列的值离散度高的 > 占用磁盘空间小的

在查询的时候,有引导列的概念存在,如果查询条件中值使用到第二列作为查询条件,而没有使用到第一列作为查询条件,那么此时是不能使用到联合索引的,

因为where条件语句中不知道第一列的值是什么,就不能根据索引树去直接使用到第二列的值。

离散度高的列排在前面,可以最快的过滤到不需要的参与查询的数据,减少磁盘的I/O交互。

占用磁盘空间小的列排在前面,可以在加载相同page页的时候,加载更多的数据行。

3. 什么是回表操作?

回表操作是指在innodb存储引擎表中,根据非聚簇索引查询数据的时候,需要从非聚簇索引的叶子节点上获取到数据行的主键值,然后再根据主键值,去聚簇索引上扫描查询,找到聚簇索引的叶子节点上数据行。这个查找数据行的过程就是回表操作。

4. 为什么会出现回表操作?

因为非聚簇索引上没有整个数据行,只有数据行的主键值。要向获取整个数据行的数据或数据行中除主键和非聚簇索引列之外的其它列的值,都需要根据主键值去聚簇索引上再去获取对应的数据列。

5. 回表操作带来的影响是什么?

回表的影响就是会增加数据查询的时候发生的磁盘I/O,降低查询的效率。

6. 如何减少是回表?

减少回表的方式,可以尝试使用覆盖索引的方式来避免回表,覆盖索引是指,非聚簇索引上的信息足够满足查询请求,不需要再回到聚簇索引上去取数据。

另外一个方式是在联合索引中利用索引下推的方式可以减少回表的次数。在查询非聚簇索引的时候,尽量的根据查询条件,筛选出更精确的查询结果,从而减少去聚簇索引中回表的次数。

这个索引下推的功能是在5.7版本中才有的,5.6版本中没有这个功能。

Tags:mysql 绝对值

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言