个人觉得自己这部分内容写得太牛逼了,所以单独抽出成一篇Blog
为什么在B+树中包含范围查询 & 使用非等值操作符会导致联合索引失效?对于这样一个问题,我们要层层刨析、分而治之。
首先,B+树的结构不仅适合精确查询,也十分适合范围查询。因为在B+树中,所有的数据都存储在叶节点中,而且所有的叶节点都必须在同一层上,且B+树的叶节点之间还会有指针相连接前后节点。
因此,根据B+树的特性,我们不妨可以将这个树作为一个链表来看:B+树的叶节点是一条长长的链表,而在链表之上,有一个索引树指向链表分为一条条的段,而我们似乎可以将B+树作为一种另类的跳表来看待。
通过上面B+树特性的分析,我们就可以简而明了地理解B+树对范围查询的支持:B+树的叶节点作为链表来看,是全局有序的。只需要通过索引找出对应的开头和结尾,就可以确定范围。
似乎我们看见了一个故人——全局有序性,而与之对应的就是局部有序性。回看我们前面的内容:
在这个B+索引树中,
user_id
全局上有序;但status
只在user_id
其中内部有序,而整个B+索引树中全局上无序
我们在对次级索引进行更详细的归纳:次级索引的有序性,是基于==单个==主要索引的有序性之上的。
是的,单个主要索引之上。到了这里问题的答案也就自然引出:
在user_id > 100
中存在多个主要索引,而在这些不同的主要索引之中的次级索引,只在单个主要索引中具有有序性,而在多个索引中、全局上是不具有有序性的。
因此我们就无法用联合索引进行SQL查询WHERE user_id > 100 AND status = 0
!
举一反三,通过上面的原理WHERE user_id = 100 AND status > 1
就可以使用联合索引,首先找到user_id = 100的节点区域,在这个主要索引内部中,status就具有局部的有效性。
最后留个思考题,like的模糊查询呢?