百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>数据库> 一文读懂MySQL中的索引
分享文章到:

一文读懂MySQL中的索引

发布时间:09/01 来源:未知 浏览: 关键词:

什么是索引

索引是一种数据构造,其作用就是用来提高数据查询效力。比力常用的比方就是将其类比为书籍的名目。通过名目可以准确的寻到某一章节的内容所在页。

在数据量较小的时候使用索引其实也没有什么意义,即便没有索引需要一条一条遍历数据关于运算机来说也并不需要太多时间。而一旦数据量较大,要包管我们能正常的对外供给效劳,包管会员使用体验那么索引就是必要的了。

索引类型

索引是一种数据构造,为了应对不一样的场景会有多种实现。在MySQL中主要就是Hash索引和B+Tree。

Hash索引

hash信赖大家应当都很熟知,hash是一种key-value情势的数据构造。实现一样是数组+链表的构造,通过hash函数运算出key在数组中的位置,然后假如显现hash冲突就通过链表来解决(拉链法)。当然还有其他的解决hash冲突的办法。hash这种数据构造是很常用的,比方我们系统使用HashMap来构建热点数据缓存,存取效力很好。

hash构造存数据第一通过运算key的hash值来肯定其在数组中的位置,假如有冲突就在该数组位置建一个链表。这样很明显有几个问题:

即便是具有雷同特点的key运算出来的位置大概相隔很远,持续查询效力低下。即不支撑范畴查询。

hash索引储备的事运算得到的hash值和行指针,而不储备详细的行值,所以通过hash索引查询数据需要停止两次查询(第一查询行的位置,然后寻到详细的数据)

hash索引查询数据的前提就是运算hash值,也就是要求key为一个能准确指向一条数据的key,所以关于like等一类的匹配查询是不支撑的。

所以我们可以知道的是hash索引适用于快速拔取某一行的数据。

B+Tree构造

从名字上看这明显是一种树构造,在大学期间数据构造的课本上树构造是必讲的。树构造是一种特殊重要的数据构造,在许多地方都会使用到。

上面我们说到hash索引没法停止范畴查询,在树构造中也有一种利便停止有序查询的构造--二叉搜索树。二叉搜索树的构造中要求父节点的值大于左孩子节点并且小于右孩子节点,如下图:

1564735832(1).png

上图中二叉树的查询的时间复杂度为O(log(n)),当然要包管O(log(n))的时间复杂度就需要包管二叉树时刻保持均衡。

而在MySQL索引中虽然也使用了树构造,但是并不是使用的二叉树。由于在数据库中数据终究都是存置在磁盘上的,而假如树的节点过多的话,那么在节点之间转移会花费较多的时间。在MySQL的实现中选中将更多内容放在统一个节点,对统一个节点的操纵转入在内存中完成,减少在外存中节点之间转移的次数,以到达提高效力的目的。这就是B+Tree,在B+Tree的实现中一个三层的树构造就根本上可以知足我们几乎所有的需求了。

相关引荐:《mysql数据库知识学习》

B-Tree

要理解B+Tree第一就得理解B-Tree,B-Tree是一种均衡树,这里的B指的是Balance而不是Binary,更确切的说B-Tree是一种多路均衡搜索树。

多路均衡搜索树如下图:

1564735844(1).png

这是一种2-3树,意思就是每个节点存有两个值,同时每个节点分支数为3,从上图中可以看出来着中构造很适合查询数据。每个节点的左子树的值都是小于当前节点中最小的值,中心的子树的值全都是在当前节点两个值的中心,而右子树的值全都大于当前节点的最大值。

比方我们要查寻24这个值:

(1)第一从根节点推断24在根节点(15,25)之间,所以摆布子树排除,从中心查寻。

(2)然后寻到中心子树的根节点(18,22),比力发明24大于该节点最大值,排除左子树和中心子树。

(3)寻到右子树,推断节点大值恰好等于24,查询完毕。

基于上面的流程可以总结B树的搜索:

(1)从根结点开端,对结点内的关键字(有序)序列停止二分查寻。

(2)假如命中则完毕,不然进入查询关键字所属范畴的子结点;

(3)反复上面的流程,直到所对应的子节点为空,或已经是叶子结点;

可以看出其搜干脆能相当于在关键字汇合内做一次二分查寻。从这里看来仿佛B-Tree没有什么问题,但是需要留意到的是在B-Tree中每一个节点都是储备索引关键字乃至其代表的详细行数据。而在MySQL中数据库加载数据是以页为单位加载,每一页的大小是牢固的(默许16k)。假如每一个节点都储备所有的值,那么一页中能存下的节点就会很少,一次查询大概就会停止屡次从内存中去加载数据,致使机能落低。

B+Tree

B+Tree是对B-Tree的一个变种,让其愈加顺应于停止外部储备文件索引。

两者此前最大的不一样就在于B-Tree的每个节点都储备所有的数据,而B+Tree需要储备的数据都在叶子节点上,并且增添了次序拜访指针,每个叶子节点都有指向下一个相邻的叶子节点的地址。这样的构造包管了在一个内存页中可以存下更多的索引节点,并且愈加适合停止范畴查询。

索引

由于储备引擎负责实现索引,所以接下来计议索引都是基于MySQL的InnoDB引擎。

聚簇索引

聚簇的意思是表示数据行和相邻的键值聚簇的储备在一起。一些数据库同意选中详细的某一个索引作为聚簇索引,而在InnoDB的实现中直接将主键索引指定为聚簇索引。假如没有定义主键,InnoDB 会选中一个独一的非空索引来代替主键索引。假如一样没有定义这样的索引,InnoDB会隐式定义一个主键来作为聚簇索引(row_id)。

聚簇索引实例如图:

1564735920(1).png

非聚簇索引索引

在InnoDB中除主键索引外其他都是非聚簇索引,所以也叫非主键索引。非主键索引的叶节点并不是储备一行的值,而是储备详细行的主键值。不知足聚簇的定义。

非聚簇索引实例如图:

1564735928(1).png

聚簇索引和非聚簇索引在查询时的差别

由上面的两种索引实例图就可以看出来,在查询时假如是通过主键索引查询的话直接查询到数据行然后返回。但是假如是通过非主键索引查询的话第一需要通过该索引肯定主键,然后通过得到的主键从主键索引中查到详细行的数据,后面的通过得到的主键从主键索引中猎取数据的历程被称为回表。

回表的历程使得通过一般索引查询较主键索引查询多了一步,在许多状况下效力相对较低。所以在我们的查询历程中假如能够仅通过主键肯定数据那最好就是直接使用主键停止查询。

覆盖索引

上面介绍了通过非主键查询会有一个回表的历程,但是需要留意的是并不是每一个查询都存在回表这一步,关于一个一般索引来说其叶节点储备的是主键的值,那么假设我此刻需要的数据也仅仅就是主键的值呢?通过一般索引取到主键的值后就并不需要再到主键索引中查,那么也就不存在回表这一历程了。

上面例子中该非主键索引已经存在了我们所需要的值,所以该索引也被称为覆盖索引。覆盖索引并不是一个牢固的构造,可以使单索引(一个字段的索引),也可以使复合索引,但凡能够直接供给查询结果而不需要停止回表历程的都可以被称为覆盖索引。

许多时候我们不成能仅仅通过主键来肯定数据,使用一般索引大概会致使低效,所以覆盖索引在日常开发历程中也是一个很常用的机能优化的手段。

当然覆盖索引页并不都是好的,比方我此刻创立了一个索引index(a,b)。由a,b两个字段来创立索引,好处已经说过了就是查询ab字段时不会回表,但是假如仅仅通过b字段来查询就没法走这个索引了。创立的索引的索引项是依照索引定义里面显现的字段次序排序的。

最左前缀原则

假设此刻存在索引index(a,b),那么假如通过a和b来查询能够利用该索引,独自使用a来查询也能利用到该索引,但是假如独自使用b来查询则没法利用到该索引。这就是最左前缀原则,在匹配索引时回匹配索引最左边的n个字段,能匹配上就可以利用该索引。

由于最左前缀原则的存在也就要求我们在创立索引时大概需要思考更多的事情。

第一需要分明的事索引是一种数据构造,创立索引时需要耗损储备空间的,所以索引并不是创立的多多益善,而是应当按照需求尽大概的减少索引的数目。

而最左前缀原则的存在就使得一个结合索引可以被当做多个索引来使用,当然前提是设计好索引中字段的次序(实际上最左前缀原则也并不是仅仅适用于结合索引,关于字符串索引也使用,字符串索引中最左n个字符相当于结合索引中的最左n个字段)。

比方index(a,b),有了这个索引后我们就不需要独自为a创立索引,所以在设计结合索引时一样将使用频率较高的字段放在前面。

然后是将区分度较高的字段靠前,区分度就是字段中值的反复率,反复率越低区分度越高。比方性别就不适合作为索引,区分度越高的字段经过一次挑选能过滤掉更多的行。

然后还需要思考的是字段的大小,由于索引也需要占据空间所以一样选用较小的字段。

参照 材料

MySQL运维内参:MySQL、Galera、Inception中心道理与最好实践

以上就是一文读懂MySQL中的索引的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有150人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板