首页 > 解决方案 > 升级后,Mongodb Atlas 开始出现 IOPS 和页面错误,并且查询速度非常慢

问题描述

在我们升级集群或主节点更改后,我们遇到了 Mongodb Atlas 的零星性能问题。[升级过程是由 MongoDb Atlas 服务自动完成的,因此我们对此机制的了解有限]

集群类型为:M30(8Gb 内存)升级 4.2 -> 4.4 预置 IOPS:1500

升级后(从 4.0 -> 4.2 也发生了这种情况),我们将看到 IOPS 超过 80% 的预置警报,并发生页面错误,图表最好地解释了这一点:

显示性能的指标

另一个重要的观察是,非常慢的查询似乎没有适当地利用索引:

例如,这个查询(略删)

{
  "command": {
    "count": "projects",
    "query": {
      "$and": [
       {
          "account": {
            "$oid": "RETRACTED"
          }
        },
        ....
        ....
        ....
"planSummary": [
    {
      "IXSCAN": {
        "account": 1,
        "hasTemplateChildren": 1,
        "templateParent": 1,
        "lastEditedAt": -1
      }
    },
    {
      "IXSCAN": {
        "templateParent": 1
      }
    }
  ],
  "keysExamined": 1604628,
  "docsExamined": 1631743,

这表明正在使用所需的索引,但仍在检查超过 160 万个键和文档。整个projects表大约有 190 万行,任何一个帐户最多有 30k 行项目。

希望这是足够的信息。提前感谢您的帮助。

标签: mongodbindexingmongodb-atlas

解决方案


更新,我们已经解决了这个问题,似乎问题出在我遗漏的部分查询上,为了清楚起见,在此处发布。查询计划器似乎因为一个特定的表达式而感到困惑:

{
   "$or": [
    {
      "templateParent": {
          "$exists": false
       }
    },
    {
       "templateParent": null
     }
    ]
 }

正是它导致整个索引(templateParent 上的索引)作为子 inputStage 的一部分被扫描。

将上面的表达式更改为:

  {
    "templateParent": null
  }

允许查询计划器执行更明智的查询。

如果有人愿意提供更深入的解释,说明为什么这会使查询计划器表现得更好,请这样做。


推荐阅读