MongoDB 计划缓存的影响

简介:

MongoDB 2.6 复制集Primary创建索引后,发现Secondary的查询没有走最新的索引。

 

临时清理掉该集合的计划缓存后正常。笔者观察到出现性能问题时,语句并没有走最优的执行计划。

 

对于MongoDB 3.0.3及之前的版本,可以通过如下两种方法得到解决:   
1. 对于查询显式指定hints。    
2. 设置查询计划缓存索引过滤器来重写默认查询计划。

 

在3.0.4版本中修复了。

SERVER-15225,SERVER-20139   
https://jira.mongodb.org/browse/SERVER-15225

    执行计划cache的刷新问题,对同一种类查询,执行计划有cache就不去验证,同一种类查询但是条件不同可能的执行情况也不同。

    可以通过internalQueryCacheReplanningEnabled参数的设置来解决   
    The query optimizer caches plans for each query shape and reuses these plans for a time. In situations where the performance of the cached plan is poor for a particular instance of the query shape, the optimizer may select a the plan with poor performance and fail to evict the cache entry. This behavior may impact deployments where two queries with the same shape have different performance characteristics if they have different selectivity.    
    This improvement makes the query planner evaluate the cost of the cached query plan, and if the cost of this plan is too high, the query planner switches to a more efficient plan. This more efficient plan is then cached for future use.    
    This improvement is not enabled by default. To enable by default set the internalQueryCacheReplanningEnabled parameter totrue using the setParameter command on a running system, or at start time using the setParameter commandline option orsetParameter in the configuration file.    
    For example, to enable using setParameter:    
    db.runCommand({setParameter: 1, internalQueryCacheReplanningEnabled: true})    
    This improvement can be disabled as follows:    
    db.runCommand({setParameter: 1, internalQueryCacheReplanningEnabled: false})    
    3.0.4可以使用这个参数,默认是关闭

 

查询计划

在给定可用索引的情况下,MongoDB查询优化器处理查询并且选择出针对某查询而言最高效的查询计划。每次查询执行的时候,查询系统都会使用该查询计划。


查询优化器只会对那些看起来有多个可行计划的查询计划进行缓存。


集合内容发生改变的时候,查询优化器会重新评估查询计划,以保证最优的查询计划。您可以通过使用 索引过滤器 来指定优化器评估的索引。


针对一个给定查询,您可以使用 explain() 方法查看查询计划的统计。

 

查询计划修订

伴随着集合随着时间的变化而变化,在下面几种情形之一,查询优化器都会删除查询计划并且对其进行重新评估:   
    1. 集合接收1,000个写操作。    
    2. The reIndex rebuilds the index.    
    3. 您增加或者删除一个索引。    
    4. The mongod process restarts.

 

缓存查询计划接口

2.6新版功能


MongoDB提供了查询计划缓存命令和方法来查看和修改已缓存的查询计划。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
db.runCommand( { planCacheListFilters: Product } )
db.runCommand(    
    {    
       planCacheListPlans:  "Product" ,    
       query: { Path: /^9-1-6(-\d+)*$/,  "Status" : { $lt: 4 } }    
    }    
)
db.runCommand(    
    {    
       planCacheClear:  "Product" ,    
       query: { Path: /^9-1-6(-\d+)*$/,  "Status" : { $lt: 4 } }    
    }    
)
db.runCommand(    
    {    
       planCacheClear:  "Product"    
    }    
)

索引过滤器

2.6 新版功能.


索引过滤器会决定优化器评估哪一个索引作为一个 query shape 。一个查询形状由查询、排序以及映射说明组成。如果一个给定的查询形状存在一个索引过滤器,优化器将只会考虑过滤器中指定的这些索引。


当查询形状中存在一个索引过滤器时,MongoDB将会忽略 hint() 。如果您想了解MongoDB是否对一个查询使用了索引过滤器,您可以检查一下 explain() 输出的 explain.filterSet 字段。


索引过滤器只会影响到优化器评估的索引,优化器有可能会仍然选择集合扫描作为某给定查询形状的优胜方案。


索引过滤器只存在于服务器进程中,在关机之后并不会保存。MongoDB也提供了一个命令手动删除过滤器。


由于索引过滤器重写了优化器以及 hint() 方法预期的操作,请合理使用索引过滤器。

1
2
3
4
5
6
7
8
9
10
11
db.runCommand(  
    {    
       planCacheSetFilter:  "orders" ,    
       query: { item:  "ABC"  },    
       projection: { quantity: 1, _id: 0 },    
       sort: { order_date: 1 },    
       indexes: [    
          { item: 1, order_date: 1 , quantity: 1 }    
       ]    
    }    

















本文转自UltraSQL51CTO博客,原文链接:http://blog.51cto.com/ultrasql/1712538  ,如需转载请自行联系原作者

相关文章
|
缓存 NoSQL MongoDB
缓存为什么要用Redis,而不是使用MongoDB呢?
缓存为什么要用Redis,而不是使用MongoDB呢?
281 0
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
741 0
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
845 0
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
1034 0
|
存储 缓存 NoSQL
Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存|学习笔记
快速学习 Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存
Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存|学习笔记
|
存储 消息中间件 缓存
【Java面试】缓存为什么用Redis而不用MongoDB呢?
分享一道面试题,问出这种问题,我觉得实在是也没什么意思。 但是今天还是稍微来分析一下,毕竟总会有人问 1 加 1 为什么等于 2。 首先,我们来想一下,既然是用来做缓存,必须要符合哪些特征呢?
340 0
|
存储 缓存 JSON
SpringBoot整合MongoDB(实现一个简单缓存)
SpringBoot整合MongoDB的一个小Demo,适合上手!
2252 0
SpringBoot整合MongoDB(实现一个简单缓存)
|
7月前
|
NoSQL MongoDB 数据库
数据库数据恢复—MongoDB数据库数据恢复案例
MongoDB数据库数据恢复环境: 一台操作系统为Windows Server的虚拟机上部署MongoDB数据库。 MongoDB数据库故障: 工作人员在MongoDB服务仍然开启的情况下将MongoDB数据库文件拷贝到其他分区,数据复制完成后将MongoDB数据库原先所在的分区进行了格式化操作。 结果发现拷贝过去的数据无法使用。管理员又将数据拷贝回原始分区,MongoDB服务仍然无法使用,报错“Windows无法启动MongoDB服务(位于 本地计算机 上)错误1067:进程意外终止。”
|
7月前
|
缓存 NoSQL Linux
在CentOS 7系统中彻底移除MongoDB数据库的步骤
以上步骤完成后,MongoDB应该会从您的CentOS 7系统中被彻底移除。在执行上述操作前,请确保已经备份好所有重要数据以防丢失。这些步骤操作需要一些基本的Linux系统管理知识,若您对某一步骤不是非常清楚,请先进行必要的学习或咨询专业人士。在执行系统级操作时,推荐在实施前创建系统快照或备份,以便在出现问题时能够恢复到原先的状态。
677 79

推荐镜像

更多