参考 > MongoDB CRUD操作 > MongoDB CRUD概念 > 查询计划
在本页面
对于查询,MongoDB查询优化器会根据可用索引选择并缓存最有效的查询计划。works
当查询计划者评估候选计划时,最有效的查询计划的评估基于查询执行计划执行的“工作单位”()的数量。
关联的计划缓存条目用于具有相同查询形状的后续查询。
从MongoDB 4.2开始,缓存条目与状态关联:
州 | 描述 |
---|---|
失踪 | 高速缓存中不存在此形状的条目。 对于查询,如果形状的缓存条目状态为 Missing:
|
不活跃 | 缓存中的条目是此形状的占位符条目。也就是说,计划者已经看到了形状并计算了其成本( 对于查询,如果形状的缓存条目状态 为非活动: |
活性 | 缓存中的条目用于中奖计划。计划者可以使用该条目来生成查询计划。 对于查询,如果形状的缓存条目状态为 Active: 活动条目用于生成查询计划。 计划者还评估条目的性能,如果条目的
|
有关触发对计划缓存进行更改的其他方案,请参阅计划缓存刷新。
要查看给定查询的查询计划信息,可以使用
db.collection.explain()
或cursor.explain()
。
从MongoDB 4.2开始,您可以使用$planCacheStats
聚合阶段来查看集合的计划缓存信息。
如果mongod
重新启动或关闭,查询计划缓存将不会保留。此外:
用户还可以:
PlanCache.clear()
方法手动清除整个计划缓存
。PlanCache.clearPlansByQuery()
方法手动清除特定的计划缓存条目
。也可以看看
queryHash
和planCacheKey
¶queryHash
¶为了帮助识别具有相同查询形状的慢速查询,从MongoDB 4.2开始,每个查询形状都与一个queryHash关联。的queryHash
是代表查询形状的散列,并且仅依赖于所述查询形状的十六进制字符串。
注意
与任何哈希函数一样,两个不同的查询形状可能会导致相同的哈希值。但是,不同查询形状之间不会发生哈希冲突。
planCacheKey
¶为了提供对查询计划缓存的更多了解,MongoDB 4.2引入了planCacheKey。
planCacheKey
是与查询关联的计划缓存条目的键的哈希值。
注意
不同于queryHash
,它planCacheKey
是查询形状和该形状当前可用索引的函数。即,如果添加/删除了可以支持查询形状的索引,则该planCacheKey
值可能会更改,而该
queryHash
值不会更改。
例如,考虑foo
具有以下索引的集合:
集合上的以下查询具有相同的形状:
给定这些查询,具有部分过滤器表达式的索引可以支持查询操作2,但不
支持查询操作1。由于可用于支持查询操作1的索引不同于查询操作2,因此两个查询具有不同的
planCacheKey
。
如果删除了一个索引,或者添加了新索引,则两个查询操作的都会更改。{ x: 1, a: 1
}
planCacheKey
该queryHash
和planCacheKey
在可供选择:
queryPlanner.queryHash
和
queryPlanner.planCacheKey
$planCacheStats
聚合阶段(MongoDB 4.2中的新增功能)PlanCache.listQueryShapes()
方法/ planCacheListQueryShapes
命令PlanCache.getPlansByQuery()
方法/ planCacheListPlans
命令索引过滤器确定优化器为查询形状评估的索引 。查询形状由查询,排序和投影说明的组合组成。如果给定查询形状存在索引过滤器,那么优化器仅考虑过滤器中指定的那些索引。
当查询形状存在索引过滤器时,MongoDB将忽略
hint()
。要查看MongoDB是否对查询形状应用了索引过滤器,请检查或
方法的indexFilterSet
字段。db.collection.explain()
cursor.explain()
索引过滤器仅影响优化器评估的索引;对于给定的查询形状,优化器仍然可以选择将集合扫描作为获胜计划。
索引过滤器在服务器进程的持续时间内存在,并且在关闭后不会持续存在。MongoDB还提供了手动删除过滤器的命令。
因为索引过滤器会覆盖优化器和hint()
方法的预期行为,所以请谨慎使用索引过滤器。
见planCacheListFilters
,
planCacheClearFilters
和planCacheSetFilter
。
也可以看看