索引数据结构选择

Hash

Hash索引效率高,那为什么用树作为常用的索引结构呢

  • 原因1: Hash索引仅能满足(=) (◇)和IN查询。如果进行范围查询,哈希型的索引,时间复杂度会退化为o(n);而树型的“有序”特性,依然能够保持o(log2N)的高效率。
  • 原因2: Hash索引还有一个缺陷,数据的存储是没有顺序的,在ORDER BY的情况下,使用Hash索引还需要对数据重新排序。
  • 原因3:对于联合索引的情况,Hash值是将联合索引键合并后一起来计算的,无法对单独的一个键或者几个索引键进行查询。
  • 原因4∶对于等值查询来说,通常Hash索引的效率更高,不过也存在一种情况,就是索引列的重复值如果很多,效率就会降低。这是因为遇到Hash冲突时,需要遍历桶中的行指针来进行比较,找到查询的关键字,非常耗时。所以,Hash索引通常不会用到重复值多的列上,比如列为性别、年龄的情况等。

Hash结构一般用于缓存数据库


B-tree

在这里插入图片描述

如何用 B 树进行查找。假设我们想要 查找的关键字是 9 ,那么步骤可以分为以下几步:

  1. 与根节点的关键字 (26,35)进行比较,9 小于 26 那么得到指针 P1;
  2. 按照指针 P1 找到磁盘块 2,关键字为(8,12),因为 9 在 8 和 12 之间,所以我们得到指针 P2;
  3. 按照指针 P2 找到磁盘块 6,关键字为(9,10),然后我们找到了关键字 9。

B+ 树和 B 树的差异:

  • 有 k 个孩子的节点就有 k 个关键字。也就是孩子数量 = 关键字数,而 B 树中,孩子数量 = 关键字数+1(比如个数上 关键字26 + 35 + 1= p1 + p2 + p3 = 3个,也就是数据并没有孩子指针)。
  • 非叶子节点的关键字也会同时存在在子节点中,并且是在子节点中所有关键字的最大(或最小)。
  • 非叶子节点仅用于索引,不保存数据记录,跟记录有关的信息都放在叶子节点中。而 B 树中, 非叶子节点既保存索引,也保存数据记录 。最根本的区别B+树的中间节点并不直接存储数据
  • 所有关键字都在叶子节点出现,叶子节点构成一个有序链表,而且叶子节点本身按照关键字的大小从小到大顺序链接。

InnoDB的B+树索引结构也提供自适应Hash索引,也就是对于一些经常用到的数据,InnoDB会存储到Hash表中,下次查询就会直接从自适应Hash表中

为什么会优化B-tree得到B+tree

  • B+树的查询效率更高。这是因为通常B+树比B树更矮胖(B+tree阶数更大,深度更低),查询所需要的磁盘I/o也会更少。同样的磁盘页大小,B+树可以存储更多的节点关键字。
  • 不仅是对单个关键字的查询上,在查询范围上,B+树的效率也比B树高。这是因为所有关键字都出现在B+树的叶子节点中,叶子节点之间会有指针,数据又是递增的,这使得我们范围查找可以通过指针连接查找。而在B树中则需要通过中序遍历才能完成查询范围的查找,效率要低很多。(就是查询两个叶子节点,B-tree需要返回父节点去遍历,导致会比B+tree链表遍历慢)

问题

Hash 索引与 B+ 树索引的区别

  • Hash索引不能进行范围查询,而B+树可以。这是因为Hash索引指向的数据是无序的,而B+树的叶子节点是个有序的链表。
  • Hash索引不支持联合索引的最左侧原则(即联合索引的部分索引无法使用),而B+树可以。对于联合索引来说,Hash索引在计算 Hash值的时候是将索引键合并后再一起计算Hash值,所以不会针对每个索引单独计算Hash值。因此如果用到联合索引的一个或者几个索引时,联合索引无法被利用。
  • Hash索引不支持ORDER BY排序,因为Hash索引指向的数据是无序的,因此无法起到排序优化的作用,而B+树索引数据是有序的,可以起到对该字段ORDER BY排序优化的作用。同理,我们也无法用Hash索引进行模糊查询,而B+树使用LIKE进行模糊查询的时候,LIKE后面后模糊查询(比如%结尾)的话就可以起到优化作用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值