数据库之索引

1、索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。

2、索引的出现是为了提高查询效率,但是实现索引的方式却有很多种,所以这里也就引入了索引模
型的概念。可以用于提高读写效率的数据结构很多,这里我先给你介绍三种常见、也比较简单的
数据结构,它们分别是哈希表、有序数组和搜索树。

2、哈希表:
假设,你现在维护着一个身份证信息和姓名的表,需要根据身份证号查找对应的名字,这时对应
的哈希索引的示意图如下所示:
图中,User2和User4根据身份证号算出来的值都是N,但没关系,后面还跟了一个链表。假设,
这时候你要查ID_card_n2对应的名字是什么,处理步骤就是:首先,将ID_card_n2通过哈希函
数算出N;然后,按顺序遍历,找到User2。
需要注意的是,图中四个ID_card_n的值并不是递增的,这样做的好处是增加新的User时速度会
很快,只需要往后追加。但缺点是,因为不是有序的,所以哈希索引做区间查询的速度是很慢
的。
你可以设想下,如果你现在要找身份证号在[ID_card_X, ID_card_Y]这个区间的所有用户,就必
须全部扫描一遍了。
在这里插入图片描述

2、有序数组:
这里我们假设身份证号没有重复,这个数组就是按照身份证号递增的顺序保存的。这时候如果你
要查ID_card_n2对应的名字,用二分法就可以快速得到,这个时间复杂度是O(log(N))。
同时很显然,这个索引结构支持范围查询。你要查身份证号在[ID_card_X, ID_card_Y]区间的
User,可以先用二分法找到ID_card_X(如果不存在ID_card_X,就找到大于ID_card_X的第一
个User),然后向右遍历,直到查到第一个大于ID_card_Y的身份证号,退出循环。
如果仅仅看查询效率,有序数组就是最好的数据结构了。但是,在需要更新数据的时候就麻烦
了,你往中间插入一个记录就必须得挪动后面所有的记录,成本太高。
所以,有有序序数数组组索索引引只只适适用用于于静静态态存存储储引引擎擎,
在这里插入图片描述

3、二叉搜索树:
二叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子。这样如果你要查
ID_card_n2的话,按照图中的搜索顺序就是按照UserA ->UserC->UserF ->User2这个路径得
到。这个时间复杂度是O(log(N))。
当然为了维持O(log(N))的查询复杂度,你就需要保持这棵树是平衡二叉树。为了做这个保证,更
新的时间复杂度也是O(log(N))。
树可以有二叉,也可以有多叉。多叉树就是每个节点有多个儿子,儿子之间的大小保证从左到右
递增。二叉树是搜索效率最高的,但是实际上大多数的数据库存储却并不使用二叉树。其原因
是,索引不止存在内存中,还要写到磁盘上。
你可以想象一下一棵100万节点的平衡二叉树,树高20。一次查询可能需要访问20个数据块。在
机械硬盘时代,从磁盘随机读一个数据块需要10 ms左右的寻址时间。也就是说,对于一个100
万行的表,如果使用二叉树来存储,单独访问一个行可能需要20个10 ms的时间,这个查询可真
够慢的。
在这里插入图片描述

4、基于主键索引和普通索引的查询有什么区别?
如果语句是select *fromTwhere ID=500,即主键查询方式,则只需要搜索ID这棵B+树;
如果语句是select *fromTwhere k=5,即普通索引查询方式,则需要先搜索k索引树,得到ID
的值为500,再到ID索引树搜索一次。这个过程称为回表。
也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主
键查询。

5、分析索引:
如果我执行 select *fromTwhere k between 3 and 5,需要执行几次树的搜索操作,会扫描多少行?
在这里插入图片描述
现在,我们一起来看看这条SQL查询语句的执行流程:

  1. 在k索引树上找到k=3的记录,取得 ID = 300;
  2. 再到ID索引树查到ID=300对应的R3;
  3. 在k索引树取下一个值k=5,取得ID=500;
  4. 再回到ID索引树查到ID=500对应的R4;
  5. 在k索引树取下一个值k=6,不满足条件,循环结束。
    在这个过程中,回到主键索引树搜索的过程,我们称为回表。可以看到,这个查询过程读了k索引树的3条记录(步骤1、3和5),回表了两次(步骤2和4)

如果执行的语句是select ID fromTwhere k between 3 and 5,这时只需要查ID的值,而ID的值
已经在k索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面,
索引k已经“覆盖了”我们的查询需求,我们称为覆盖索引。
由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值