下面两条语句有什么区别,为什么都提倡使用范围查询 ?
- select * from T where k in(1,2,3,4,5)
- select * from T where k between 1 and 5
其实between和in这两个关键字应用的场景重合度并不高,但是我们可以通过思考这么一个问题,来理清这两者执行的执行过程和逻辑。
要回答这个问题就需要先了解索引的数据结构,以及mysql索引利用b+树执行查询的执行过程,这里先默认大家具备了这个条件。
先区分下可能的情况。
第一个是k字段是主键,第二个是k字段是二级索引,第三种情况是k是普通字段。
另外,我们需要搞清楚in关键字和between两种查询方式在执行的时候的不同之处;
- in关键字其实是等值查询的合并,将多个等值查询合并成一个,减少查询和返回次数;
- between查询是典型的范围查询,在命中索引的情况下,会直接在查询首个符合条件的数据,然后根据指针一次获取下一个叶子节点数据进行比较直到查询到不符合条件的数据为止。
现在我们再来对三种情况进行梳理,
k是主键索引和二级索引的情况是相似的,唯一的区别就是二级索引的话可能需要回表,回表不是这次讨论的重点,所以我们把这两种情况合并到一起说;
in 条件实际查询的时候是多次搜索索引树,而 between 条件只需要执行一次搜索树的查询就可以获得结果,本题为例,加入索引的底层实现结构使用的是b+树,使用关键字 in 要树搜素5次,也就是做5次等值查询;而 bewteen 基于b+树的范围查询逻辑,当找到第一个满足条件的叶子节点后,根据当前叶子节点指向的下一个叶子节点继续查询,直到查到不满足条件的叶子节点,所以只需要树搜索一次。
而对于k不是索引的情况,in条件相当于执行了多次的全文遍历,而between其实也是全文遍历,都不是一个好的方式。