在mongodb中,为什么查询索引的子文档数组比索引的第一级文档更快?

时间:2013-07-27 07:05:42

标签: mongodb indexing bigdata database

这就是我的数据库的样子:

> show dbs
admin   0.203125GB
local   0.078125GB
profiler    63.9228515625GB
> use profiler
switched to db profiler
> show collections
documents
mentions

提及的文件是这样的:

> db.mentions.findOne()
{
    "_id" : ObjectId("51ec29ef1b63042f6a9c6fd2"),
    "corpusID" : "GIGAWORD",
    "docID" : "WPB_ENG_20100226.0044",
    "url" : "http://en.wikipedia.org/wiki/Taboo",
    "mention" : "taboos",
    "offset" : 4526
}

文档中的文档如下所示:

> db.documents.findOne()
{
    "_id" : ObjectId("51ec2d981b63042f6ae4ca0b"),
    "sentence_offsets" : [
        ..................
    ],
    "docID" : "WPB_ENG_20101020.0002",
    "text" : ".........",
    "verb_offsets" : [
    .............
    ],
    "mentions" : [
        {
            "url" : "http://en.wikipedia.org/wiki/Washington,_D.C.",
            "mention" : "Washington",
            "ner" : "ORG",
            "offset" : 122
        },
        ...................
    ],
    "corpusID" : "GIGAWORD",
    "chunk_offsets" : [
        .................
    ]
}

提及的文件有1亿份,文件有130万份。 mentions中出现的每个提及也应该出现在某个document的{​​{1}}数组中。我在文档中存储提及信息的原因是为了避免提到检索上下文。然而,当我仅查询提及时,我认为拥有一个独立的集合mentions应该更快。

但是,在我对mentions / mentions.urlmentions.mention / documents.mentions.url上的索引进行实验,并在两个集合中查询相同的网址/提及后,我发现它是从文件收集中获得响应的速度是提及收集的两倍。

我不确定索引是如何在内部工作的,但我认为两个索引都有相同的大小,因为两个集合中的提及数量相同。因此他们应该有相同的响应时间?

我正在尝试像

这样的东西
documents.mentions.mention

因此网络开销不应有差异。

这是

的输出
> db.mentions.find({url: "http://en.wikipedia.org/wiki/Washington,_D.C."}).explain()

> db.mentions.find({mention: "Illinois"}).explain()

{
"cursor" : "BtreeCursor mention_1",
"isMultiKey" : false,
"n" : 4342,
"nscannedObjects" : 4342,
"nscanned" : 4342,
"nscannedObjectsAllPlans" : 4342,
"nscannedAllPlans" : 4342,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 14,
"nChunkSkips" : 0,
"millis" : 18627,
"indexBounds" : {
    "mention" : [
        [
            "Illinois",
            "Illinois"
        ]
    ]
},
"server" : "----:----"
}

和统计数据(是的,我恢复了收藏并没有索引文件。还是):

> db.documents.find({"mentions.mention": "Illinois"}).explain()

{
"cursor" : "BtreeCursor mentions.mention_1",
"isMultiKey" : true,
"n" : 3102,
"nscannedObjects" : 3102,
"nscanned" : 3102,
"nscannedObjectsAllPlans" : 3102,
"nscannedAllPlans" : 3102,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 8,
"nChunkSkips" : 0,
"millis" : 7862,
"indexBounds" : {
    "mentions.mention" : [
        [
            "Illinois",
            "Illinois"
        ]
    ]
},
"server" : "----:----"
}

如果有人能告诉我为什么会这样,我将不胜感激。 :

1 个答案:

答案 0 :(得分:0)

  

提及的文件有1亿份,而有300万份   文档。

两个索引中都有相同数量的索引条目,因为您告诉我们您在文档和提及中都存储了提及。

因此索引访问时间 相同。您可以通过从两者运行覆盖索引查询来衡量这一点 - 这意味着您只想获取存储在索引中的值:db.x.find({url:"xxx"}, {_id:0, "url":1})表示查找匹配文档并仅返回其中的url值。如果这两个连接中的两个不相等,那么您的设置可能有些不寻常,或者其中一个索引无法适应RAM或其他与测量相关的问题。

如果这两个是相同的,但提取文档在文档收集方面总是更快,我会检查并查看原因 - 完整的解释输出可以显示花费的时间 - 以及是否更多例如,一个集合比其他集合恰好存在于RAM中。