OPTIONS
翻译或纠错本页面

查询计划

在给定可用索引的情况下,MongoDB查询优化器处理查询并且选择出针对某查询而言最高效的查询计划。每次查询执行的时候,查询系统都会使用该查询计划。

查询优化器只会对那些看起来有多个可行计划的查询计划进行缓存。

集合内容发生改变的时候,查询优化器会重新评估查询计划,以保证最优的查询计划。您可以通过使用 索引过滤器 来指定优化器评估的索引。

针对一个给定查询,您可以使用 explain() 方法查看查询计划的统计。 indexing strategies 中的信息可以在您开发的过程中为您提供帮助。

查询优化

为了创建一个新的查询计划,查询优化器:

  1. 在几个候选索引上并行运行查询。

  2. 在一个共同的结果区缓存或多个缓存中记录这些匹配。

    • 如果候选计划中只包括 有序查询计划 ,就只会存在一个单一的通用结果缓存区。

    • 如果候选计划中只包括 无序查询计划 ,也只会存在一个单一的通用结果缓存区。

    • 如果候选计划 同时 包括 有序查询计划无序查询计划 ,那么这里就会有两个通用结果缓存区,一个是为有序计划准备的,另一个则是为无序计划准备的。

    如果一个索引返回另一个索引已经返回过的结果,该优化器将会跳过重复的匹配。在两个缓存的情况下,两个缓存都会被重复删除。

  3. 下列情形之一发生的时候,就会停止测试候选计划然后选择一个索引:

    • 一个 无序查询计划 已经返回了所有匹配的结果; 或者

    • 一个 有序查询计划 已经返回了所有匹配的结果; 或者

    • 一个 有序查询计划 已经返回了阈值数量匹配的结果; 或者

      • 2.0版本: 阈值是批量查询的大小。默认批量大小是101。

      • 2.2版本:阈值为101。

选定的索引成为查询计划中指定的索引。有相同查询模式的查询的后期迭代都将会使用该索引。查询模式指的是查询选择条件只是在值上不想同,下面的两个查询就拥有相同的查询模式:

db.inventory.find( { type: 'food' } )
db.inventory.find( { type: 'utensil' } )

查询计划修订

伴随着集合随着时间的变化而变化,在下面几种情形之一,查询优化器都会删除查询计划并且对其进行重新评估:

  • 集合接收1,000个写操作。

  • The reIndex rebuilds the index.
  • 您增加或者删除一个索引。

  • The mongod process restarts.

缓存查询计划接口

2.6 新版功能.

MongoDB提供了 Query Plan Cache Methods 来查看和修改已缓存的查询计划。

索引过滤器

2.6 新版功能.

索引过滤器会决定优化器评估哪一个索引作为一个 query shape 。一个查询形状由查询、排序以及映射说明组成。如果一个给定的查询形状存在一个索引过滤器,优化器将只会考虑过滤器中指定的这些索引。

当查询形状中存在一个索引过滤器时,MongoDB将会忽略 hint() 。如果您想了解MongoDB是否对一个查询使用了索引过滤器,您可以检查一下 explain() 输出的 explain.filterSet 字段。

索引过滤器只会影响到优化器评估的索引,优化器有可能会仍然选择集合扫描作为某给定查询形状的优胜方案。

索引过滤器只存在于服务器进程中,在关机之后并不会保存。MongoDB也提供了一个命令手动删除过滤器。

由于索引过滤器重写了优化器以及 hint() 方法预期的操作,请合理使用索引过滤器。

请参照 planCacheListFiltersplanCacheClearFilters 以及 planCacheSetFilter