大家好,今天小编关注到一个比较有意思的话题,就是关于用搜索引擎查阅资料的好处的问题,于是小编就整理了1个相关介绍用搜索引擎查阅资料的好处的解答,让我们一起看看吧。
数据库中的索引,原理是什么?为什么查询使用索引就会快?
相信很多程序员朋友对数据的索引并不陌生,最常见的索引是 B+ Tree 索引,索引可以加快数据库的检索速度,但是会降低新增、修改、删除操作的速度,一些错误的写法会导致索引失效等等。
但是如果被问到,为什么用了索引之后,查询就会变快?B+ Tree 索引的原理是什么?这时候很多人可能就不知道了,今天我就以 MySQL 的 InnoDB 引擎为例,讲一讲 B+ Tree 索引的原理。
索引的基础知识
MySQL 的基本存储结构是页,大概就是这个样子的:
在这里,我们需要了解以下几点(非常重要):
当我们用 MySQL 的 InnoDB 引擎创建表,有且只能有一个主键;如果我们没有显示地指定之间,那么MySQL 会自动生成一个隐含字段作为主键;
聚集索引:以主键创建的索引;聚集索引的叶子节点存储的是表中的数据;
非聚集索引:非主键创建的索引;非聚集索引在叶子节点存储的是主键和索引列;使用非聚集索引查询数据,会查询到叶子上的主键,再根据主键查到数据(这个过程叫做回表)。
页和页之间、页和数据之间的关系
我们以聚集索引做讲解,页和页之间、以及页和数据之间的关系是这样的:
数据页和数据页之间,组成一个双向链表;
每个数据页中的记录,是一个单向链表;
每个数据页都根据内部的记录生成一个页目录(Page directory),如果是主键的话,可以在页目录中使用二分法快速定位;
如果我们根据一个非主键、非索引列进行查询,那么需要遍历双向链表,找到所在的页;再遍历页内的单向链表;如果表内数据很大的话,这样的查询就会很慢。
B+ Tree 索引的原理
先让我们看看 B+ Tree 索引大概是什么样子(以聚集/主键索引为例):
假如这时候我们要查询 id = 16 的数据:
查询页-1,找到页-2 存储的是小于 30 的数据;
查询页-2,找到页-5 存储的是 10~20 的数据;
查询页-5,找到 id = 16 的数据。
很显然,没有用索引的时候,需要遍历双向链表来定位对应的页,而有了索引,则可以通过一层层“目录”定位到对应的页上。
为什么 B+ Tree 索引会降低新增、修改、删除的速度
B+ Tree 是一颗平衡树,如果对这颗树新增、修改、删除的话,会破坏它的原有结构;
我们在做数据新增、修改、删除的时候,需要花额外的时间去维护索引;
正因为这些额外的开销,导致索引会降低新增、修改、删除的速度。
思考题,欢迎留言讨论
现在你是否理解了 B+ Tree 索引的原理?
最后再留一个思考题:为什么官方建议使用自增长主键作为索引?大家可以在留言中写下你的答案。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注;关注我后,可私信发送数字【1】,获取海量学习资料。
索引是存储引擎用于快速查找记录的数据结构,MySQL 数据库内部索引是由不同的引擎实现的,主要说一下最常用的InnoDB引擎中的索引,InnoDB引擎中的索引是使用B+ 树的结构来存储的,B+ 树结构如下图:
先来说一下B+ 树的特点:
叶子节点(最下面一层)存储关键字(索引字段的值)信息及对应的全部数据记录。
非叶子节点只存储关键字的信息及子节点的指针。
每个叶子节点相当于MySQL中的一个数据页,同层级的叶子节点以双向链表的形式连接。
每个节点中存储了多条记录,记录之间用单链表的形式连接组成了一条有序的链表。
在 B+ 树中检索数据时:每次检索都从根节点开始,一直搜索到叶子节点。
InnoDB 的数据是按数据页为单位来读写的。也就是说,当需要读取一条记录的时候,并不是将这个记录本身从磁盘读取出来,而是以页为单位,将整个也加载到内存中,一个页中可能有很多记录,然后在内存中对页通过二分法进行检索。在InnoDB 中,每个页的大小默认是16kb。
总体来说,MySQL中的索引用到了B+树、链表、二分法,实现了快速查找数据。
MySQL索引类型
InnoDB 中有两种索引类型:主键索引与辅助索引。
主键索引(聚集索引):每个表只有一个主键索引,叶子节点同时保存了主键的值以及对应的全部记录。
辅助索引(非聚集索引):叶子节点保存了索引字段的值以及主键的值。
我们以上图中Person表 为例,其中id 是主键,name 是辅助索引,接下里我们来看一下InnoDB引擎中数据检索过程:
若需要查询 id=1 的数据,只需要使用主键索引中检索就可以查询到数据。(红色线)
若需要搜索 name='Jacy' 的数据,需要使用非聚集索引与聚集索引,需要2步(蓝色线):
先通过辅助索引中检索 name='Jacy'的数据,获取 id 的值。
再通过id值 到主键索引中 检索id=12的数据。
接下来,我们再看下以下查询的数据检索过程。
主键索引(或唯一索引)查询
上图中所有的数据都是唯一的,我们查询26的记录,过程如下:
首先把page1 页加载到内存中通过二分法查找。
确定26位于[20,40)中间,然后加载20所关联的page3 页.
将page3 页加载到内存中,采用二分法找到26的记录后退出。
非唯一索引查询
上图中查询26的所有记录,数据不唯一,过程如下:
将page1 页加载到内存中通过二分法查找。
确定26位于[20,40)中间,然后加载20所关联的page3 页。
将page3 页加载到内存中通过二分法找到最后一个小于26的记录是23,然后通过链表从23开始向后访问,找到所有的26记录,直到遇到第一个大于26的值退出。
模糊查询
上图中查询以 b字母开头的所有记录,过程如下:
将page1页加载到内存中,通过二分法查找最后一个小于等于b的值(b),和第一个大于b的(z),b指向叶节点page3,z指向叶节点page5。
如此一来,可以确定以 b 开头的记录存在于[page3,page5) 这个范围内。
最后依次加载page3 到内存中,通过二分法找到第一条b开头的记录,然后以链表方式继续向后访问page4 中的记录,直至遇到一个字母为z的值退出。
当我们使用 '%b%' 全模糊查询时,通过索引我们还可以快速定位所在的页嘛?
如上图包含b字母的数据在每个页中都存在,因此无法判断包含 b 的记录在哪些页中,只能通过IO的方式加载所有页,遍历所有记录进行过滤,才可以找到包含b的记录。因此使用LIKE %b%进行全模糊查询时,索引是无效的。
更多内容可以浏览《MySQL数据库中如何正确的理解与使用索引》https://www.toutiao.com/i6759910720944472588/
这个问题和线性查询、二分查询是有很大关系的。索引后的数据可以使用二分法查询,未索引的数据查询需要线性查询。下面详细说一下这两者之间的性能区别。
1、两者的查询原理
①、线性查询
线性查询又称顺序查询,它的查询原理就是从第一条记录开始,逐个比较要查找的字段,直到字段内容和查找值相等,则查找成功,返回结果。若比较结果与字段所有记录都不等,则查找失败。下面举例说明:
需要在某个记录数为N的数组a[]中查找元素k,那么,线性查询就是从a[1]开始和k进行对比,对比相等则返回a[i],如果,不相等则继续下一个查询, i=i+1。直到 i=N为止。那线性查询的性能就一目了然:
- 最好的情况就是对比1次就找到结果。
- 最差的情况就是需要对比N次才能找到结果。
- 平均计算,就是N/2次能找到结果。
②、二分查询
二分法查询也可以说是分段查询。主要原理就是对已经排序的一组数据进行中间分段,中间分界点和查询值对比。如果数值小于分界点,则要查找的数落在前半段;如果数字大于分界点,则要查找的数落在前半段;如果等于分界点,则要查找数就已经找到。下面同样举例说明:
需要在某个记录数为N且已经排好序的数组a[]中查找元素K,那么,二分查询首先是确定数组的中点a[x],其实也就是a[N/2]这个值(N/2采用进一法取整)。然后对比a[x]和K值,按照前面的方法循环缩小对比的区间,最终找到想要的值。二分查询的性能如下:
- 二分法查询N条记录需要log2(N)次对比就能找到结果。
- 前提是:数组必须要排好序
★从上面两种查询法原理可以看到,当数组N比较大时,二分查询的查询性能明显优于线性查询。当数组N较小时,则线性查询的性能更好,因为它少了求中值的开销。
2、索引给数据库查询带来的性能变化
数据库中建立索引其实就是对数据库表中一列或多列的值进行排序的结构。其实就是为了给二分查询做好排序的前提。结合前面两种查询的原理,我们就很容易理解数据库中索引变快的原因了。其实,数据库通常情况下,数据量都是比较大的,一般都是上万条,甚至达到亿级记录。我们用前面原理中的公式计算对比一下:
- 在10万条记录中查找一个值:那么,N=100000;
- 线性查询性能=N/2,计算可得,平均需要对比50000次;
- 二分查询性能=log2(N),计算可得,大约需要17次;
从上面计算对比,我们可以看到,索引好了用二分查询的性能会比线性查询快非常多。
3、数据库哪里应该加索引
虽然加了索引后,查询性能提升很多。但是在数据库里面也是不所有字段都加索引的,因为,数据库的整体性能不仅需要考虑查询性能,还需要考虑写入性能。当你在数据库中某个字段加入索引后,该字段就需要建立对应的索引指针。每次新写入或者修改字段的记录,都需要额外写入索引指针。所以,在数据库中,加入索引会加快搜索性能,但也会相应降低一点点写入性能。所以,数据库中建立索引一般在以下几种情况建立索引。
- 经常需要搜索的列,增加索引可以加快搜索速度;
- 作为主键的列,强制该列的唯一性和组织表中数据的排列结构;
- 在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
- 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的
- 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间
- 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度
总结
总之,数据库中因为存在大量的数据,建立索引相当于对数据进行了排序,可以使用二分查询法来查询数据,确实会大大提高查询的速度。但是也会相应降低一点点写入的速度,所以,数据库中的索引也是有针对性的建立索引的。
感谢阅读!我是数智风,用经验回答问题,欢迎评论关注。
到此,以上就是小编对于用搜索引擎查阅资料的好处的问题就介绍到这了,希望介绍关于用搜索引擎查阅资料的好处的1点解答对大家有用。