2011-09-21 258 views
4

我们有一个大约1M文件的mongo数据库,我们想要使用处理字段查询这个数据库以查找我们以前没有看到的文档。为此,我们正在设置一个名为_processed的新字段。MongoDB查询具有不存在字段和索引的记录

要查询哪些需要处理的文件,我们查询的文件不具有这个处理场:

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

然而,这个查询需要30秒左右,每次来完成,这是相当缓慢。有一个位于_processed字段的索引(asc):

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

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

_processed字段很长,也许这应该更改为布尔使事情更快?

我们使用$哪里查询(即$where : this._processed==null)做同样的事情$exists : false尝试和性能是差不多的(几秒钟慢这是有道理的)...

任何想法上会是什么会导致性能下降(或者正常)?有没有人有关于如何提高查询速度的建议?

干杯!

+0

只是在创建文档时不是选项而只是将_processed字段设置为'false'? –

+0

感谢您的评论。这是可行的(但是作为最后的手段) - 我想避免这种倾销过程被刺激。 _processed字段在这个实例中很长,所以我们只需将它设置为类似于0或-1的值。这是一个很好的观点,但是,将处理后的字段类型更改为bool会使事情变得更快吗?处理时间很长的唯一原因是存储处理时间的时间戳(仅用于帮助进行任何调试),但实际上它可以设置为bool,如果我们确实需要它,我们可以使用_processed(bool)和_porcessed_timestamp (长)..? – NightWolf

回答

5

升级到2.0会为你做到这一点:

从MongoDB.org:

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

+0

有趣,没有知道这一点。很高兴知道! –

+2

同上,不知道这个(想想这里一个重要的教训,再次像这些RTFM时代一样)。谢谢,解决了我的问题。只需将查询更改为{'_processed':null}。 Genius DV87! – NightWolf

+0

现在运行它,查询需要整个8ms。邪恶! – NightWolf

4

其缓慢的,因为检查_processed -> not exists犯规提供多少选择性。它就像有一个“性别”索引 - 因为只有两个可能的选项malefemale那么如果你有1M行和索引Gender它将不得不扫描50%或500K行来查找所有男性。

您需要让您的索引更具选择性。

+0

感谢您的评论科迪。我看到你的观点,在Mongo中,所有的空字段都被索引。因此,如果我有一个大多数处理过的数据集,它的扫描效果并不差,但它不得不扫描每个文档。即使我做了_processed = false,它真的6打了另一半作为_processed = false或_processed = null为所有密集的目的是相等的... – NightWolf

+0

我不认为这是相关的。 MongoDB使用游标返回结果。只要这些值被索引,就没有“扫描”,结果可以尽可能快地进行回放,因为您可以抓取它们。这里的问题是搜索没有使用索引。 –

相关问题