【问题标题】:MongoDB Query for records with non-existant field & indexingMongoDB查询具有不存在字段和索引的记录
【发布时间】:2011-09-21 15:57:22
【问题描述】:

我们有一个包含大约 100 万个文档的 mongo 数据库,我们希望使用已处理的字段来轮询该数据库以查找我们以前从未见过的文档。为此,我们设置了一个名为 _processed 的新字段。

查询需要处理的文档,我们查询没有这个已处理字段的文档:

db.stocktwits.find({ "_processed" : { "$exists" : false } })

但是,此查询每次大约需要 30 秒才能完成,这相当慢。 _processed 字段上有一个索引 (asc):

db.stocktwits.ensureIndex({ "_processed" : -1 },{ "name" : "idx_processed" });

添加此索引不会改变查询性能。集合上还有一些其他索引(即 ID idx 和每个文档中几个字段的唯一索引)。

_processed 字段很长,也许应该将其更改为 bool 以加快速度?

我们尝试使用 $where 查询(即$where : this._processed==null)来做与$exists : false 相同的事情,并且性能大致相同(慢了几秒,这是有道理的)...

关于什么会导致性能缓慢(或者这是正常的)的任何想法?有人对如何提高查询速度有任何建议吗?

干杯!

【问题讨论】:

  • 创建文档时是否将_processed字段设置为false不是一个选项?
  • 感谢您的评论。这将是可行的(但作为最后的手段) - 我想避免这种情况,因为倾销过程已经被淘汰了。在这种情况下,_processed 字段很长,因此我们只需将其设置为 0 或 -1 之类的值。但是,这是一个很好的观点,将处理的字段类型更改为 bool 会使事情变得更快吗?处理的唯一原因是长是存储处理时间的时间戳(只是为了帮助任何调试目的),但实际上它可以设置为布尔值,如果我们真的需要它,我们可以有 _processed (bool) 和 _porcessed_timestamp (长)..?

标签: mongodb indexing


【解决方案1】:

升级到 2.0 将为您做这件事:

来自 MongoDB.org:

Before v2.0, $exists is not able to use an index. Indexes on other fields are still used.

【讨论】:

  • 有趣,不知道这个。很高兴知道!
  • 同上,不知道这一点(认为这里有一个重要的教训,在像这些 RTFM 再次密切相关的时候)。谢谢,解决了我的问题。只需将查询更改为 {'_processed':null}。天才 DV87!
  • 现在运行,查询需要整整 8ms。邪恶!
【解决方案2】:

它很慢,因为检查_processed -> not exists 并没有提供太多的选择性。就像在“性别”上有一个索引 - 因为只有两个可能的选项 malefemale 那么如果你有 1M 行和一个索引 Gender 它必须扫描 50% 或 500K 行才能找到所有男性。

您需要使索引更具选择性。

【讨论】:

  • 感谢您的评论科迪。我明白你的意思,在 Mongo 中,所有空字段都被索引。因此,如果我有一个主要处理的数据集,它的扫描效果还不错,它比扫描每个文档都要好。即使我设置了 _processed = false,它实际上是 6 个半打,因为 _processed = false 或 _processed = null 对于所有密集目的都是等效的......
  • 我认为这无关紧要。 MongoDB 使用游标返回结果。如果这些值被索引,则没有“扫描”,结果可以以尽可能快的速度流回。这里的问题是搜索没有使用索引。
猜你喜欢
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
  • 2018-02-07
  • 2014-09-09
  • 2016-07-10
  • 1970-01-01
相关资源
最近更新 更多