如果我们在Collection建了5个index,那么当我们查询的时候,MongoDB会根据查询语句的筛选条件、sort排序等来定位可以使用的index作为候选索引;然后MongoDB会创建对应数量的查询计划,并分别使用不同线程执行查询计划,最终会选择一个执行最快的index;但是这个选择也不是一成不变的,后续还会有一段时间根据实际执行情况动态调整;
二、数据准备 三、正则对index的使用MongoDB支持正则查询,在特定的情况其也是可以利用index获得查询性能的提升;
虽然MongDB执行正则会最大限度的使用index,但是不同的用法还是会影响对index的利用程度的;
执行以下普通正则表达式
从queryPlanner.winningPlan部分的COLLSCAN,可以看到正则表达式默认会进行全表的扫描;
从executionStats.executionStages部分可以看到COLLSCAN共扫描了1000000个文档,并返回1111个文档,总耗时794ms;
创建一个包含name的index;
再次执行上边的查询,可以看到使用了我们新建的name_1索引;但是从执行状态来看,还是扫描了全体的索引的key,并不能很好的利用index;
使用前缀匹配的话可以最大限度的利用index,从执行状态可以看到只检测了1111个index key;
即使是前缀匹配,如果忽略大小写的话也无法充分利用index了;
四、$or从句对索引的利用MongoDB执行$or从句的时候,会将所有的从句作为逻辑的整体,要不就都使用index,要不就都进行全表扫描;
执行以下的查询语句;
在只有name_1这个index的时候,我们可以看到MongoDB进行了全表扫描,全表扫描的时候进行$or从句的过滤;
我们对name字段新建一个index;
再次执行以上的查询语句,这次可以看到每个从句都利用了index,并且每个从句会单独执行并最终进行or操作;
五、sort对索引的利用如果sort操作无法利用index,则MongoDB就会在内存中排序数据,并且数据量一大就会报错;
如果是单字段index,sort从两个方向都可以充分利用index;可以看到MongoDB直接按照index的顺序返回结果,直接就没有sort阶段了;
对于复合索引,sort除了可以从整体上从两个方向利用index,也可以利用index的前缀索引和非前缀局部索引;
新建复合索引
按照复合索引的反方向进行整体排序;
排序使用索引前缀,也需要保证字段的顺序,但是可以反方向排序;
排序如果使用的是非前缀的局部字典排序,name需要保证前边的字段是等值筛选操作才行;
六、搜索数据对索引命中的影响MongoDB对index的选择是受到实际场景的数据影响比较大的,即与实际数据的分布规律有关,也跟实际筛选出来的数据有关系;所以我们对索引的优化和测试都需要考虑实际的数据场景才行;
由于name的字段值筛选出来的key太多,不能充分利用index,所以MongoDB拒绝了name_1并选择了age_1;
我们修改一下name筛选条件的值,进一步缩小命中的范围,可以看到这次MongoDB选择了name_1;
总结到此这篇关于MongoDB中哪几种情况下的索引选择策略的文章就介绍到这了,更多相关MongoDB索引选择策略内容请搜索七叶笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持七叶笔记!