大厂面试必备(一)——数据库索引的本质解析

一、索引概述

      索引是半数数据库高效获取数据的排好序的数据结构。
      索引数据结构:二叉树、红黑树、Hash表、B-Tree。

在这里插入图片描述

二叉树

      如上图所示是一个二叉树的结构,但是索引不会是二叉树的数据结构。从上图我们可以看出右边节点始终大于父节点,可以想象,当我们用Col1做索引列的时候,形成的二叉树是一个只有右节点的二叉树(线型,类似成了链表结构)。所以用二叉树做索引是有弊端的,所以mysql最终没有选择用它来实现索引。
Col1做索引的二叉树

红黑树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
      如图所示,当插入0004时,右边的节点比左边的节点多了一层。当插入0005时,有点的节点可能回比左边的节点多两层。此时,红黑树会通过自旋,让此时0002节点的右子树的层数控制在不超过左子树两层。红黑树也就是平衡二叉树,也是优化后的普通二叉树。但是,我们也可以发现这样的问题,当数据量比较大的时候,红黑树的高度也会很高,一次比较就得经过一次磁盘IO,如果查询的数据刚好在叶子节点,同样会导致查询效率的问题。

B-Tree

(1)叶节点具有相同的深度,叶节点的指针为空;
(2)所有索引元素不重复;
(3)节点中的数据索引从左到右递增排列。
在这里插入图片描述
      如图所示是B-Tree的结构,由图可知B-Tree一个节点有多个数据。当进行查询时,会一次性将一个节点上的所有数据都加载到内存中,也就是进行一次IO,接着在内存里面进行查找和对比。要知道,在内存里面随机查找一个数据是很快的。
      那么,我们可不可以将所有数据都放到一个节点上,一次性全部数据加载到内存然后再对比查找?答案是否定的,一、RAM内存有限,数据可能很多甚至上千万条;二、一次磁盘IO也没办法查太多数据。
在这里插入图片描述
      根据sql查询结果可知,mysql设置了每个节点的大小为16kb。

B+Tree(B-Tree变种)
  • 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引;
  • 叶子节点包含所有索引字段;
  • 叶子节点用指针链接,提高区间访问的性能;
  • 任意一个节点上的数据从左到右是递增的。

在这里插入图片描述
      我们假设上图中的索引数字为bigint(大小为8B),每个索引后面跟着一个指向下一个节点的指针(大小为6B)。前面我们知道一个节点的大小为16KB,那么一个非叶子节点可以存储的索引数量为16KB/(8B+6B)= 1170。假设B+Tree的高度为3,叶子节点索引与Data大小为1KB(根据节点的大小为16KB,即叶子节点可以放16个元素),且每个节点都放满了,那么叶子节点总共大概可以存放多少数据。1170117016=21902400,由此可知,千万级别的表,精确的用某个比较合适的索引去查,它的性能依然能够非常高。即使两千万的数据,也只需要经历两次磁盘IO就可以查询出结果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章