On this page本页内容
For a query, the MongoDB query optimizer chooses and caches the most efficient query plan given the available indexes. 对于查询,MongoDB查询优化器根据可用索引选择并缓存最有效的查询计划。The evaluation of the most efficient query plan is based on the number of "work units" (在查询计划员评估候选计划时,最有效的查询计划的评估基于查询执行计划执行的“工作单元”(works
) performed by the query execution plan when the query planner evaluates candidate plans.works
)数量。
The associated plan cache entry is used for subsequent queries with the same query shape.关联的计划缓存条目用于具有相同查询形状的后续查询。
Starting in MongoDB 4.2, the cache entry is associated with a state:从MongoDB 4.2开始,缓存条目与以下状态关联:
| |
| |
|
See 请参阅Plan Cache Flushes计划缓存刷新 for additional scenarios that trigger changes to the plan cache.用于触发计划缓存更改的其他场景。
To view the query plan information for a given query, you can use 要查看给定查询的查询计划信息,可以使用db.collection.explain()
or the cursor.explain()
.db.collection.explain()
或cursor.explain()
。
Starting in MongoDB 4.2, you can use the 从MongoDB 4.2开始,可以使用$planCacheStats
aggregation stage to view plan cache information for a collection.$planCacheStats
聚合阶段查看集合的计划缓存信息。
The query plan cache does not persist if a 如果mongod
restarts or shuts down. mongod
重新启动或关闭,查询计划缓存不会持久。In addition:此外:
Users can also:用户还可以:
PlanCache.clear()
method.PlanCache.clear()
方法手动清除整个计划缓存。PlanCache.clearPlansByQuery()
method.PlanCache.clearPlansByQuery()
方法手动清除特定的计划缓存项。Starting in MongoDB 5.0 (and 4.4.3, 4.2.12, 4.0.23, and 3.6.23), the plan cache will save full 从MongoDB 5.0(以及4.4.3、4.2.12、4.0.23和3.6.23)开始,只有当所有集合的计划缓存的累积大小小于0.5 GB时,计划缓存才会保存完整的计划缓存项。plan cache
entries only if the cumulative size of the plan caches
for all collections is lower than 0.5 GB. When the cumulative size of the 当所有集合的计划缓存的累积大小超过此阈值时,将存储其他计划缓存项,而不包含以下调试信息:plan caches
for all collections exceeds this threshold, additional plan cache
entries are stored without the following debug information:
The estimated size in bytes of a 计划缓存项的估计大小(以字节为单位)可在plan cache
entry is available in the output of $planCacheStats
.$planCacheStats
的输出中获得。
queryHash
and planCacheKey
queryHash
To help identify slow queries with the same query shape, starting in MongoDB 4.2, each query shape is associated with a queryHash. 为了帮助识别具有相同查询形状的慢速查询,从MongoDB 4.2开始,每个查询形状都与一个queryHash关联。The queryHash
is a hexadecimal string that represents a hash of the query shape and is dependent only on the query shape.queryHash
是一个十六进制字符串,表示查询形状的散列,并且仅依赖于查询形状。
As with any hash function, two different query shapes may result in the same hash value. 与任何哈希函数一样,两个不同的查询形状可能会产生相同的哈希值。However, the occurrence of hash collisions between different query shapes is unlikely.但是,不同查询形状之间不太可能发生哈希冲突。
planCacheKey
To provide more insight into the query plan cache, MongoDB 4.2 introduces the planCacheKey.为了更深入地了解查询计划缓存,MongoDB 4.2引入了planCacheKey
。
planCacheKey
is a hash of the key for the plan cache entry associated with the query.是与查询关联的计划缓存项的密钥哈希。
Unlike the 与queryHash
, the planCacheKey
is a function of both the query shape and the currently available indexes for the shape. queryHash
不同,planCacheKey
是查询形状和形状当前可用索引的函数。That is, if indexes that can support the query shape are added/dropped, the 也就是说,如果添加/删除支持查询形状的索引,planCacheKey
value may change whereas the queryHash
value would not change.planCacheKey
值可能会更改,而queryHash
值不会更改。
For example, consider a collection 例如,考虑具有以下索引的集合foo
with the following indexes:foo
:
db.foo.createIndex( { x: 1 } ) db.foo.createIndex( { x: 1, y: 1 } ) db.foo.createIndex( { x: 1, z: 1 }, { partialFilterExpression: { x: { $gt: 10 } } } )
The following queries on the collection have the same shape:集合上的以下查询具有相同的形状:
db.foo.explain().find( { x: { $gt: 5 } } ) // Query Operation 1 db.foo.explain().find( { x: { $gt: 20 } } ) // Query Operation 2
Given these queries, the index with the partial filter expression can support query operation 2 but notsupport query operation 1. 给定这些查询,带有部分筛选表达式的索引可以支持查询操作2,但不支持查询操作1。Since the indexes available to support query operation 1 differs from query operation 2, the two queries have different 由于可用于支持查询操作1的索引不同于查询操作2,因此这两个查询具有不同的planCacheKey
.planCacheKey
。
If one of the indexes were dropped, or if a new index 如果删除了其中一个索引,或者添加了一个新的索引{ x: 1, a: 1 }
were added, the planCacheKey
for both query operations will change.{ x: 1, a: 1 }
,则两个查询操作的planCacheKey
都将更改。
The queryHash
and planCacheKey
are available in:queryHash
和planCacheKey
在以下位置提供:
explain()
queryPlanner.queryHash
queryPlanner.planCacheKey
mongod
/mongos
日志消息)。$planCacheStats
PlanCache.listQueryShapes()
planCacheListQueryShapes
PlanCache.getPlansByQuery()
planCacheListPlans
Index filters are set with the 索引筛选器使用planCacheSetFilter
command and determine which indexes the optimizer evaluates for a query shape. planCacheSetFilter
命令设置,并确定优化器为查询形状计算的索引。A query shape consists of a combination of query, sort, and projection specifications. 查询形状由查询、排序和投影规范的组合组成。If an index filter exists for a given query shape, the optimizer only considers those indexes specified in the filter.如果给定查询形状存在索引筛选器,优化器只考虑筛选器中指定的索引。
When an index filter exists for the query shape, MongoDB ignores the 当查询形状存在索引筛选器时,MongoDB会忽略hint()
. hint()
。To see whether MongoDB applied an index filter for a query shape, check the 要查看MongoDB是否对查询形状应用了索引筛选器,请检查indexFilterSet
field of either the db.collection.explain()
or the cursor.explain()
method.cursor.explain()
或cursor.explain()
方法的indexFilterSet
字段。
Index filters only affect which indexes the optimizer evaluates; the optimizer may still select the collection scan as the winning plan for a given query shape.索引筛选器只影响优化器评估的索引;优化器仍然可以选择集合扫描作为给定查询形状的获胜计划。
Index filters exist for the duration of the server process and do not persist after shutdown. 索引筛选器在服务器进程期间存在,并且在关闭后不会持续存在。MongoDB also provides a command to manually remove filters.MongoDB还提供了手动删除筛选器的命令。
Because index filters override the expected behavior of the optimizer as well as the 因为索引筛选器会覆盖优化器以及hint()
method, use index filters sparingly.hint()
方法的预期行为,所以要谨慎使用索引筛选器。
See 请参见planCacheListFilters
, planCacheClearFilters
, and planCacheSetFilter
.planCacheListFilters
、planCacheClearFilters
和planCacheSetFilter
。