数据库
首页 > 数据库> > 数据库索引的灵魂拷问?

数据库索引的灵魂拷问?

作者:互联网

最近一直在回顾一些数据库的知识,顺便就整理了一下一些常见的面试题以及关于一些容易被忽略的知识点,会陆续的在今后的文章里面展示出来,欢迎大家讨论,共同学习。今天我们聊一下关于索引底层的问题,聊聊为什么索引要设计成这个样子

正如我们知道的,索引的目的是提高查询的速度,对于一些数据量不大的表,我们是否建索引并不重要,因为数据量不大对于磁盘查找来说都是很快的,但是当数据量达到了万级、百万、千万级别的时候,我们的查找速度就不能按照原有的循序查询,必须按指定路线去查找以达到我们提高查询的目的。索引的本质就是为查询数据提供一些便捷的路线,就像去图书馆找书,我们不用一本一本的去找,可以先把书按照按规则存在,比如按大类存放(如属于文学类或者是历史类的),然后在按照各类的子类区分(如历史类可以按朝代划分)。。。。。,通过这样的路线或者规则的指定,我们就可以更为有效快捷的找到书籍.

  1. 创建索引和维护索引要耗费时间,每次的新增和修改数据,都需要维护索引。这样的时间随着数据 量的添加而添加。
  2. 索引须要占物理空间,除了数据表占数据空间之外,每个索引还要占一定的物理空间.
  3. 所以索引不是越多越好的

这个问题有很多的讲究,需要一定的经验和足够扎实的基础,并非一两句能解释清楚的,足够单独一篇文章进行讲解了 简单来说:建立在经常使用到的列,权衡好优缺点,当优点大于缺点的问题时,就是最合适的

  1. 哈希类型:一种以键-值(key-value)存储数据的结构,我们只要输入待查找的值即key,就可以找到其对应的值即Value ,常用于等值查询
  2. 有序数组类型:适用场景:只适用于静态存储引擎。用于等值查询和范围查询(ID值必须是递增的)
  3. 搜索树类型:左子节点小于父节点、父节点小于右子节点。Innodb使用B+树(后面会说为什么使用B+树作为索引)

我们知道:哈希的查询/插入/修改/删除的平均时间复杂度都是O(1);树,例如平衡二叉搜索树,查询/插入/修改/删除的平均时间复杂度都是O(lg(n))。那为何还要使用树结构呢:

  1. 哈希索引适合等值查询,但是无法进行范围查询,而范围查询在数据库的使用中是经常被使用到的
  2. 哈希索引没办法利用索引完成排序
  3. 哈希索引不支持多列联合索引的最左匹配规则
  4. 如果有大量重复键值的情况下,哈希索引的效率会很低,因为存在哈希碰撞问题

作为扩展,我们认识一下其他的一些常见的树结构为什么不能被使用,有什么优缺点

  1. 二叉查找树

缺点如下: 二叉查找树只有两路,所以当数据量大的时候,会造成树的高度很高,查询的时候会进行多次的磁盘查找,影响查找速度,另外就是,作为非平衡树,极端的情况下会形成单路链表

  1. B树

 

  1. B树是一种多路自平衡的搜索树,可以有效的减低树的高度,提高查询的效率
  2. 可以达到预读的效果,利用到局部性的原理,能把查询的数据附近的数据一起返回,减低查询的磁盘IO

从上面的点看,B树已经足够的优秀,但是呢Mysql采用的B+树类型是在B树的基础上进行升级,让查询的性能更为优异

      3. B+树

  1. B+树集成了B树的优点,另外,B树在的非叶子节点不在保留数据,只保留索引,这就意味着同样的大小的磁盘页可以容纳更多节点元素
  2. B树的查找只需找到匹配元素即可,最好情况下查找到根节点,最坏情况下查找到叶子结点,所说性能很不稳定,而B+树每次必须查找到叶子结点,性能稳定
  3. 另外B树的范围查找需要不断依赖中序遍历。首先二分查找到范围下限,在不断通过中序遍历,知道查找到范围的上限即可。整个过程比较耗时。而B+树的范围查找则简单了许多。首先通过二分查找,找到范围下限,然后同过叶子结点的链表顺序遍历,直至找到上限即可,整个过程简单许多,效率也比较高。

总结

标签:数据量,拷问,数据库,查询,索引,查找,哈希,节点
来源: https://www.cnblogs.com/xiaoyangcoding/p/15014942.html