【问题标题】:MongoDB is extremely slow when using count() on array在数组上使用 count() 时,MongoDB 非常慢
【发布时间】:2016-08-29 11:36:45
【问题描述】:

简介

我的收藏有超过 100 万份文档。每个文档的结构都是相同的,如下所示:

{_id: "LiTC4psuoLWokMPmY", number: "12345", letter: "A", extra: [{eid:"jAHBSzCeK4SS9bShT", value: "Some text"}]}

所以,如您所见,我的extra 字段是一个包含小对象的数组。我正在尝试尽可能多地插入这些对象(直到我接近 16MB 的文档限制)。这些对象通常出现在集合中最多文档的extra 数组中。所以我通常有数十万个相同的对象。

我在 extra 数组中的 eid 键上有一个索引。我使用这个创建了这个索引:

db.collectionName.createIndex({"extra.eid":1})

问题

我想计算集合中有多少 extra 字段对象。我正在这样做:

db.collectionName.find({extra: {eid: "jAHBSzCeK4SS9bShT"}}).count()

一开始,上面的查询很快。但是每当extra 数组变大一点(超过 20 个对象)时,它就会变得非常慢。

对于 3-4 个对象,它需要不到 100 毫秒,但是当它变得更大时,需要更多的时间。对于 50 个对象,需要 6238 毫秒。

问题

  1. 为什么会这样?
  2. 我怎样才能加快这个过程?
  3. 有没有其他方法可以更快地完成这个过程?

【问题讨论】:

  • 考虑为“额外”创建一个索引。
  • @FelipeSulser 不幸的是,这是不可能的,因为索引键太大。
  • 使用聚合是否会更快,因为我认为使用查找和计数不是正确的方法。例如 db.collectionName.aggregate({$group: {_id: "$extra.eid", count: {$sum:1}}});
  • @WhiteBullet 聚合比查找和计数要快,但不是那么多。

标签: arrays mongodb performance


【解决方案1】:

我遇到了similar problem。我敢打赌您的查询没有达到您的索引。

你可以做一个解释(在 Mongo shell 中运行 db.collectionName.find({extra: {eid: "jAHBSzCeK4SS9bShT"}}).explain())来确定。

原因是在 Mongo 中 db.collectionName.find({extra: {eid: "jAHBSzCeK4SS9bShT"}})db.collectionName.find({"extra.eid": "jAHBSzCeK4SS9bShT"}) 不一样。第一种形式不会使用您的索引,而第二种形式将(例如,尽管这在您的情况下不起作用,因为您的子文档实际上是一个数组)。不知道为什么,但这似乎是 Mongo 查询构建器的一个怪癖。

除了索引整个子文档之外,我没有找到任何解决方案。

【讨论】:

  • 哇,我不知道。非常感谢!第二个查询的速度是原来的两倍。你是对的,第一个没有使用索引。你说第二个查询对我不起作用;但它有效。我错过了什么吗?
  • 如果能用就太好了!我只是不确定,因为我只在不是数组的子文档上使用了该语法。可以肯定的是,您可以在其上运行 explain() 并确保它正在使用索引。很高兴它运行得更快:-) FWIW,我仍然不确定这种行为是有意的还是错误的......
  • 效果很好!是的,我使用explain() 来检查索引的使用情况,只有第二个显示它正在被使用。我重新设计了extra 字段,它现在包含更复杂的对象。我为每个文档插入了 70 个对象,第一个查询(不使用索引),count 用了 7357 毫秒,而第二个查询(使用索引),count 只用了 104 毫秒。我希望这不是错误 :) 再次非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 2018-01-09
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
相关资源
最近更新 更多