- MongoDB官方文档中文版
- MongoDB中文手册说明
- MongoDB简介
- 安装 MongoDB
- The mongo Shell
- MongoDB CRUD 操作
- 聚合
- 数据模型
- 事务
- 索引
- 安全
- 安全检查列表
- 启用访问控制
- 身份验证
- 基于角色的访问控制
- TLS / SSL(传输加密)
- 静态加密
- 客户端字段级加密
- 审计
- 网络和配置强化
- 实现字段级别修订
- 安全参考
- 附录
- 变更流
- 复制
- 分片
- 分片键
- 哈希分片
- 范围分片
- 区
- 管理分片区
- 按位置细分数据
- 用于更改SLA或SLO的分层硬件
- 按应用或客户细分数据
- 仅插入工作负载的分布式本地写入
- 管理分片区
- 使用块进行数据分区
- 在分片集群中拆分数据块
- 管理
- 存储
- 存储引擎
- 日志记录
- 管理日志记录
- GridFS
- FAQ:MongoDB 存储
- 存储引擎
- 参考
- 运算符
- 查询与映射运算符
- 更新运算符
- 聚合管道阶段
- 聚合管道操作符
- $abs (aggregation)
- $acos (aggregation)
- $acosh (aggregation)
- $add (aggregation)
- $addToSet (aggregation)
- $allElementsTrue (aggregation)
- $and (aggregation)
- $anyElementTrue (aggregation)
- $arrayElemAt (aggregation)
- $arrayToObject (aggregation)
- $asin (aggregation)
- $asinh (aggregation)
- $atan (aggregation)
- $atan2 (aggregation)
- $atanh (aggregation)
- $avg (aggregation)
- $ceil (aggregation)
- $cmp (aggregation)
- $concat (aggregation)
- $concatArrays (aggregation)
- $cond (aggregation)
- $convert (aggregation)
- $cos (aggregation)
- $dateFromParts (aggregation)
- $dateToParts (aggregation)
- $dateFromString (aggregation)
- $literal (aggregation)
- 查询修饰符
- 数据库命令
- 聚合命令
- 地理空间命令
- 查询和写操作命令
- 查询计划缓存命令
- 认证命令
- 用户管理命令
- 角色管理命令
- 复制命令
- 分片命令
- 会话命令
- 管理命令
- 诊断命令
- 免费监控命令
- 系统事件审计命令
- mongo Shell 方法
- 集合方法
- db.collection.aggregate()
- db.collection.bulkWrite()
- db.collection.copyTo()
- db.collection.count()
- db.collection.countDocuments()
- db.collection.estimatedDocumentCount()
- db.collection.createIndex()
- db.collection.createIndexes()
- db.collection.dataSize()
- db.collection.deleteOne()
- db.collection.deleteMany()
- db.collection.distinct()
- db.collection.drop()
- db.collection.dropIndex()
- db.collection.dropIndexes()
- db.collection.ensureIndex()
- db.collection.explain()
- db.collection.find()
- db.collection.findAndModify()
- db.collection.findOne()
- db.collection.findOneAndDelete()
- db.collection.findOneAndReplace()
- db.collection.findOneAndUpdate()
- db.collection.getIndexes()
- db.collection.getShardDistribution()
- db.collection.getShardVersion()
- db.collection.insert()
- db.collection.insertOne()
- db.collection.insertMany()
- db.collection.isCapped()
- db.collection.latencyStats()
- db.collection.mapReduce()
- db.collection.reIndex()
- db.collection.remove()
- db.collection.renameCollection()
- db.collection.replaceOne()
- db.collection.save()
- db.collection.stats()
- db.collection.storageSize()
- db.collection.totalIndexSize()
- db.collection.totalSize()
- db.collection.update()
- db.collection.updateOne()
- db.collection.updateMany()
- db.collection.watch()
- db.collection.validate()
- 词汇表
- 默认的MongoDB端口
- 默认的MongoDB读/写关注
- 服务器会话
- MongoDB驱动
- FAQ
- 联系我们
- 更多资料
- [快学Mongo]
- [Mongo问题讨论区]
- [Mongo 驱动使用手册]
- 本书使用 GitBook 发布
查询计划
查询计划
在本页面
对于查询,MongoDB查询优化器在给定可用索引的情况下选择并缓存效率最高的查询计划。最有效的查询计划的评估是基于查询执行计划在查询计划评估候选计划时执行的“工作单元”(works)的数量。
关联的计划缓存条目用于具有相同查询形状的后续查询。
计划缓存条目状态
从MongoDB 4.2开始,缓存条目与状态关联:
State | Description |
---|---|
失踪 | 缓存中不存在此形状的条目。 对于查询,如果形状的缓存条目状态为 Missing: 1.对候选计划进行评估并选出一个获胜的计划。 2.所选计划将以非活动状态及其工作值添加到缓存中。。 |
不活跃 | 缓存中的条目是此形状的占位符条目。也就是说,计划者已经看到了形状并计算了其成本(works 价值)并存储为占位符条目,但查询形状不用于生成查询计划。
对于查询,如果形状的缓存条目状态非活动:
1.对候选计划进行评估并选出一个获胜的计划。
2.所选计划的工作值与非活动条目的工作值进行比较。如果所选计划的works值为:小于或等于非活动条目的,
所选计划将替换占位符“不 活动”条目,并具有“ 活动”状态。
如果在替换发生之前,“ 非活动”条目变为“ 活动”(例如,由于其他查询操作),则仅当新活动条目的works 值大于所选计划时,才会替换该新活动条目。
大于非活动条目的数量,
不活动的条目仍然存在,但其工作值增加。 |
活性 | 缓存中的条目用于中奖计划。计划者可以使用该条目来生成查询计划。
对于查询,如果形状的缓存条目状态为 Active:
活动条目用于生成查询计划。
计划者还评估条目的性能,如果条目的 works 值不再符合选择标准,它将转换为非活动状态。 |
有关触发对计划缓存进行更改的其他方案,请参阅计划缓存刷新。
查询计划和高速缓存信息
要查看给定查询的查询计划信息,可以使用 db.collection.explain()
或cursor.explain()
。
从MongoDB 4.2开始,您可以使用$planCacheStats
聚合阶段来查看集合的计划缓存信息。
计划缓存刷新
如果mongod
重新启动或关闭,查询计划缓存将不会保留。此外:
- 索引或收集删除之类的目录操作会清除计划缓存。
- 最近最少使用(LRU)高速缓存替换机制将清除最近最少访问的高速缓存条目,而不管其状态如何。
用户还可以:
使用
PlanCache.clear()
方法手动清除整个计划缓存 。使用
PlanCache.clearPlansByQuery()
方法手动清除特定的计划缓存条目 。
也可以看看
queryHash和planCacheKey
queryHash
为了帮助识别具有相同查询形状的慢速查询,从MongoDB 4.2开始,每个查询形状都与一个queryHash相关联。queryHash是一个十六进制字符串,表示查询形状的散列,并且只依赖于查询形状。
[success] 注意
与任何hash函数一样,两个不同的查询形状可能会导致相同的hash值。但是,不同查询形状之间不会发生哈希冲突。
planCacheKey
为了更深入地了解缓存查询计划,MongoDB 4.2引入了 planCacheKey.
planCacheKey
是与查询关联的计划缓存条目的键的hash值。
[success] 注意
与queryHash不同,planCacheKey是查询形状和当前可用的形状索引的函数。也就是说,如果添加/删除了支持查询形状的索引,planCacheKey值可能会改变,而queryHash值不会改变。
例如,考虑一个具有以下索引的foo集合:
db.foo.createIndex( { x: 1 } )
db.foo.createIndex( { x: 1, y: 1 } )
db.foo.createIndex( { x: 1, z: 1 }, { partialFilterExpression: { x: { $gt: 10 } } } )
集合上的以下查询具有相同的形状:
db.foo.explain().find( { x: { $gt: 5 } } ) // Query Operation 1
db.foo.explain().find( { x: { $gt: 20 } } ) // Query Operation 2
对于这些查询,带有部分过滤表达式 的索引可以支持查询操作2,但不支持查询操作1。由于支持查询操作1的索引与查询操作2不同,这两个查询具有不同的planCacheKey。
如果删除了其中一个索引,或者添加了一个新的索引{x: 1, a: 1},那么用于这两个查询操作的planCacheKey将会改变。
可用性
queryHash和planCacheKey是可用的在:
- explain() output字段:
queryPlanner.queryHash
和queryPlanner.planCacheKey
- 记录慢查询时,探查器日志消息 和诊断日志消息(即mongod / mongos日志消息)。
$planCacheStats
聚合阶段(MongoDB 4.2中的新增功能)- PlanCache.listQueryShapes()方法/planCacheListQueryShapes命令
- PlanCache.getPlansByQuery()方法/planCacheListPlans命令
索引筛选器
索引筛选器确定优化器为查询形状评估哪些索引。查询形状由查询、排序和投影规范的组合组成。如果存在针对给定查询形状的索引筛选器,则优化器仅考虑筛选器中指定的那些索引。
当存在查询形状的索引过滤器时,MongoDB会忽略hint()
。要查看MongoDB是否为查询形状应用了索引筛选器,请检查db.collection.explain()
或cursor.explain()
方法的indexFilterSet
字段。
索引过滤器仅影响优化器评估的索引;对于给定的查询形状,优化器仍然可以选择将集合扫描作为获胜计划。
索引过滤器在服务器进程的持续时间内存在,并且在关闭后不会持续存在。MongoDB还提供了手动删除过滤器的命令。
因为索引过滤器会覆盖优化器和hint()
方法的预期行为,所以请谨慎使用索引过滤器。
见planCacheListFilters
, planCacheClearFilters
和planCacheSetFilter
。
也可以看看:
索引策略
译者:杨帅
校对:杨帅
Copyright © 上海锦木信息技术有限公司 all right reserved,由 MongoDB汉化小组 提供技术支持文件修订时间: 2020-10-11 20:53:05