Query Plans查询计划

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.关联的计划缓存条目用于具有相同查询形状的后续查询。

Plan Cache Entry State计划缓存条目状态

Starting in MongoDB 4.2, the cache entry is associated with a state:从MongoDB 4.2开始,缓存项与以下状态关联:

StateDescription描述
Missing

No entry for this shape exists in the cache.缓存中不存在此形状的条目。

For a query, if the cache entry state for a shape is Missing:对于查询,如果形状的缓存条目状态 缺失

  1. Candidate plans are evaluated and a winning plan is selected.对候选计划进行评估,并选择获胜计划。
  2. The selected plan is added to the cache in Inactive state with its works value.选定的计划将以其works值以非活动状态添加到缓存中。
Inactive

The entry in the cache is a placeholder entry for this shape. 缓存中的条目是此形状的占位符条目。That is, the planner has seen the shape and calculated its cost (works value) and stored as a placeholder entry but the query shape is not used to generate query plans.也就是说,计划者已看到该形状并计算了其成本(works值)并存储为占位符条目,但查询形状不用于生成查询计划。

For a query, if the cache entry state for a shape is Inactive:对于查询,如果形状的缓存条目状态为“非活动”

  1. Candidate plans are evaluated and a winning plan is selected.对候选计划进行评估,并选择获胜计划。
  2. The selected plan’s works value is compared to the Inactive entry’s. 将所选计划的works值与非活动条目的工时值进行比较。If the selected plan’s works value is:如果所选计划的works值为:

    • Less than or equal to the Inactive entry’s,小于或等于非活动条目的,

      The selected plan replaces the placeholder Inactive entry and has an Active state.所选计划将替换占位符非活动条目,并处于活动状态。

      If before the replacement happens, the Inactive entry becomes Active (for example, due to another query operation), the newly active entry will only be replaced if its works value is greater than the selected plan.如果在替换之前,非活动条目变为活动条目(例如,由于另一个查询操作),则仅当新活动条目的工作值大于所选计划时,才会替换该条目。

    • Greater than the Inactive entry’s,大于非活动条目的,

      The Inactive entry remains but its works value is incremented.非活动条目保留,但其works值增加。

Active

The entry in the cache is for the winning plan. 缓存中的条目用于获胜计划。The planner can use this entry to generate query plans.计划员可以使用此条目生成查询计划。

For a query, if the cache entry state for a shape is Active:对于查询,如果形状的缓存条目状态为活动状态:

The active entry is used to generate query plans.活动条目用于生成查询计划。

The planner also evaluates the entry’s performance and if its works value no longer meets the selection criterion, it will transition to Inactive state.规划器还会评估条目的性能,如果其works值不再满足选择标准,则它将转换为非活动状态。

See Plan Cache Flushes for additional scenarios that trigger changes to the plan cache.有关触发计划缓存更改的其他场景,请参阅计划缓存刷新

Query Plan and Cache Information查询计划和缓存信息

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 $planCacheStats aggregation stage to view plan cache information for a collection.从MongoDB 4.2开始,可以使用$planCacheStats聚合阶段查看集合的计划缓存信息。

Plan Cache Flushes计划缓存刷新

The query plan cache does not persist if a mongod restarts or shuts down. 如果mongod重新启动或关闭,查询计划缓存不会持久。In addition:此外:

  • Catalog operations like index or collection drops clear the plan cache.目录操作(如索引或收集删除)会清除计划缓存。
  • Least recently used (LRU) cache replacement mechanism clears the least recently accessed cache entry, regardless of state.最近使用最少(LRU)缓存替换机制清除最近访问最少的缓存项,而不考虑状态。

Users can also:用户还可以:

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是一个十六进制字符串,表示查询形状的散列,并且仅依赖于查询形状。

Note

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.是与查询关联的计划缓存项的密钥哈希。

Note

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 not support query operation 1. 给定这些查询,带有部分筛选表达式的索引可以支持查询操作2,但不支持查询操作1。Since the indexes available to support query operation 1 differs from query operation 2, the two queries have different planCacheKey.由于可用于支持查询操作1的索引不同于查询操作2,因此这两个查询具有不同的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都将更改。

Availability可用性

The queryHash and planCacheKey are available in:queryHashplanCacheKey在以下位置可用:

Index Filters索引筛选器

Index filters determine which indexes the optimizer evaluates for a query shape. 索引筛选器确定优化器为查询形状计算的索引。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 hint(). 当查询形状存在索引筛选器时,MongoDB会忽略hint()To see whether MongoDB applied an index filter for a query shape, check the indexFilterSet field of either the db.collection.explain() or the cursor.explain() method.

Index filters only affects 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.请参见planCacheListFiltersplanCacheClearFiltersplanCacheSetFilter