- MongoDB CRUD 操作 >
- CRUD 概念 >
- 读操作 >
- 查询计划
查询计划¶
在给定可用索引的情况下,MongoDB查询优化器处理查询并且选择出针对某查询而言最高效的查询计划。每次查询执行的时候,查询系统都会使用该查询计划。
查询优化器只会对那些看起来有多个可行计划的查询计划进行缓存。
集合内容发生改变的时候,查询优化器会重新评估查询计划,以保证最优的查询计划。您可以通过使用 索引过滤器 来指定优化器评估的索引。
针对一个给定查询,您可以使用 explain() 方法查看查询计划的统计。 indexing strategies 中的信息可以在您开发的过程中为您提供帮助。
查询优化¶
为了创建一个新的查询计划,查询优化器:
在几个候选索引上并行运行查询。
在一个共同的结果区缓存或多个缓存中记录这些匹配。
如果候选计划中只包括 有序查询计划 ,就只会存在一个单一的通用结果缓存区。
如果候选计划中只包括 无序查询计划 ,也只会存在一个单一的通用结果缓存区。
如果候选计划 同时 包括 有序查询计划 和 无序查询计划 ,那么这里就会有两个通用结果缓存区,一个是为有序计划准备的,另一个则是为无序计划准备的。
如果一个索引返回另一个索引已经返回过的结果,该优化器将会跳过重复的匹配。在两个缓存的情况下,两个缓存都会被重复删除。
下列情形之一发生的时候,就会停止测试候选计划然后选择一个索引:
一个 无序查询计划 已经返回了所有匹配的结果; 或者
一个 有序查询计划 已经返回了所有匹配的结果; 或者
一个 有序查询计划 已经返回了阈值数量匹配的结果; 或者
2.0版本: 阈值是批量查询的大小。默认批量大小是101。
2.2版本:阈值为101。
选定的索引成为查询计划中指定的索引。有相同查询模式的查询的后期迭代都将会使用该索引。查询模式指的是查询选择条件只是在值上不想同,下面的两个查询就拥有相同的查询模式:
db.inventory.find( { type: 'food' } )
db.inventory.find( { type: 'utensil' } )
查询计划修订¶
伴随着集合随着时间的变化而变化,在下面几种情形之一,查询优化器都会删除查询计划并且对其进行重新评估:
索引过滤器¶
2.6 新版功能.
索引过滤器会决定优化器评估哪一个索引作为一个 query shape 。一个查询形状由查询、排序以及映射说明组成。如果一个给定的查询形状存在一个索引过滤器,优化器将只会考虑过滤器中指定的这些索引。
当查询形状中存在一个索引过滤器时,MongoDB将会忽略 hint() 。如果您想了解MongoDB是否对一个查询使用了索引过滤器,您可以检查一下 explain() 输出的 explain.filterSet 字段。
索引过滤器只会影响到优化器评估的索引,优化器有可能会仍然选择集合扫描作为某给定查询形状的优胜方案。
索引过滤器只存在于服务器进程中,在关机之后并不会保存。MongoDB也提供了一个命令手动删除过滤器。
由于索引过滤器重写了优化器以及 hint() 方法预期的操作,请合理使用索引过滤器。
请参照 planCacheListFilters 、 planCacheClearFilters 以及 planCacheSetFilter 。