如何正确的使用索引 mysql索引怎么实现( 二 )


将P1页加载到内存在内存中采用二分法查找,可以确定105位于[100,150)中间,100关联P4页将P4加载到内存中,采用二分法找到最有一个小于105的记录,即100,然后通过链表从100开始向后访问,找到所有的105记录,直到遇到第一个大于100的值为止范围搜索

如何正确的使用索引 mysql索引怎么实现


数据如上图所示,所有记录[55,150]均可查询 。由于页面是双向链表升序排列,页面内部的数据是单项升序排列,我们只需要找到范围初始值所在的位置,然后依靠链表访问两个位置之间的所有数据 。流程如下:
将P1页加载到内存内存中采用二分法找到55位于50关联的P3页中,150位于P5页中将P3加载到内存中,采用二分法找到第一个55的记录,然后通过链表结构继续向后访问P3中的60、67,当P3访问完毕之后,通过P3的nextpage指针访问下一页P4中所有记录,继续遍历P4中的所有记录,直到访问到P5中所有的150为止 。模糊匹配
如何正确的使用索引 mysql索引怎么实现


数据如上图 。
查询所有以' f '开头的记录
流程如下:
将P1数据加载到内存中在P1页的记录中采用二分法找到最后一个小于等于f的值,这个值是f,以及第一个大于f的,这个值是z,f指向叶节点P3,z指向叶节点P6,此时可以断定以f开头的记录可能存在于[P3,P6)这个范围的页内,即P3、P4、P5这三个页中加载P3这个页,在内部以二分法找到第一条f开头的记录,然后以链表方式继续向后访问P4、P5中的记录,即可以找到所有已f开头的数据查询包含“f”的记录
包含一个在sql中写成%f%的查询 。我们能通过索引快速定位页面吗?
你可以看看上面的数据 。f存在于每一页 。我们无法通过P1页面中的记录来判断哪些页面包含F 。我们只能通过io加载所有叶节点,并过滤所有记录,以找到包含F的记录..
因此,如果使用% value%,则索引对于查询无效 。
最左匹配原则
当B树中的数据项是复杂的数据结构,比如(姓名,年龄,性别)时,B树从左到右建立搜索树 。比如搜索(张三,20,F)这样的数据时,B树会先比较名字,确定下一步的搜索方向 。如果姓名相同,则依次比较年龄和性别,最终得到搜索 。但是当(20,F)这样的数据没有名字就来了,B-tree就不知道下一步要查哪个节点了,因为建立搜索树的时候名字是第一个比较因素,你必须根据名字搜索,才能知道下一步要查哪里 。比如在搜索(张三,F)这样的数据时,B树可以用name指定搜索方向,但是下一个字段age是缺失的,所以我们只能找到所有名字是张三的数据,然后匹配性别是F的数据,这是一个很重要的性质,也就是索引最左边的匹配特征 。
我们来试几个例子 。
下图是三个字段(a,b,c)的联合索引 。索引中数据的顺序以A ASC、B ASC、C ASC的排序方式存储在节点中 。索引先按A域升序排列,A相同则按B域升序排列,B相同则按C域升序排列 。仔细查看节点中的每个数据 。
如何正确的使用索引 mysql索引怎么实现


查询a=1的记录
由于页面中的记录是以A ASC、B ASC、C ASC的排序方式存储的,所以A字段是有序的,可以通过二分法快速检索 。流程如下:
将P1加载到内存中在内存中对P1中的记录采用二分法找,可以确定a=1的记录位于{1,1,1}和{1,5,1}关联的范围内,这两个值子节点分别是P2、P4加载叶子节点P2,在P2中采用二分法快速找到第一条a=1的记录,然后通过链表向下一条及下一页开始检索,直到在P4中找到第一个不满足a=1的记录为止查询a=1,b=5的记录 。

推荐阅读