MongoDB索引介绍-强制命中

时间:2025-02-18 08:03:14
  • 使用hint方法
    hint方法实现了对查询计划机制的干预,在查询计划中使用hint语句可以让mongodb忽略查询优化器的结果,从而直接使用指定的索引。
    比如下面这种做法:

    db.test.find().hint({name:1}) //强制使用{name:1}这个索引。
    db.test.find().hint("name_1") //可以传入索引的定义对象,也可以是索引的名称。
    
  • 使用IndexFilter方法

    db.runCommand({planCacheSetFilter:"test",query:{a:3,b:4},indexs:[{b:1}]})
    

    执行planCacheSetFilter命令会在test集合中增加了一个IndexFilter对象,该对象将会自动关联到同时包含a字段和b字段的等值查询,并引导查询优化器使用{b:1}这个索引。
    其中,查询模型会忽略查询条件中具体的数值,因此下面的查询时适用的:

    db.test.find({a:99,b:-1})
    

    但是,如果使用了非等值查询(如ge、lt),或者排序(sort)、投射(projection)发生了变化,就会导致匹配失效。
    indexFilter时内存台的,如果重启了mongodb,则会自动失效。另外,可以使用planCacheClearFilters进行擦除,代码如下:

    db.runCommand({planCacheClearFilters:"test"})
    

indexFilter方法优先级高于hint,如果查询优化器发现了关联的indexFilter,则一定会忽略hint语句。但是,indexFilter并不能保证查询优化器最终一定会选择对应的索引,事实上优化器会将这些索引于全表扫描一并进行评估,再抉择出最终的结果。在最坏的情况下,如果我们指定了不存在的索引,就会导致全表扫描。

注意:mongodb的查询优化器已经足够强大,无论是hint方法还是indexfilter,都会改变默认的查询优化行为,尽量少用。