为什么这个mongo查询会这么慢?

时间:2015-07-11 17:20:48

标签: javascript performance mongodb optimization mongodb-query

我试图弄清楚如何处理这种情况。最终应该是日期范围。

db.article_raw.count({
   "date": {$gt:ISODate("2015-07-08T00:00:00.000Z")},
   "searchTerms.term":"iPhone"
})

我有以下3个索引(我知道这些索引是重复的,但我试图弄清楚)

{
   "date" : 1,
   "searchTerms.term" : 1
}

{
    "date" : 1
}

{
    "searchTerms.term" : 1
}

数据看起来像

{
    title: "a cool title",
    date: ISODate("2015-07-09T11:58:36.000Z"),
    "searchTerms" : [ 
        {
            "term" : "According to Jim",
            "relevance" : "0.315"
        }, 
        {
            "term" : "iPhone",
            "relevance" : "0.057"
        }
   }
}

最后,这是find()版本的解释结果。

{
    "cursor" : "BtreeCursor date & search",
    "isMultiKey" : true,
    "n" : 275,
    "nscannedObjects" : 275,
    "nscanned" : 11022,
    "nscannedObjectsAllPlans" : 16142,
    "nscannedAllPlans" : 26889,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 1074,
    "nChunkSkips" : 0,
    "millis" : 59548,
    "indexBounds" : {
        "date" : [ 
            [ 
                ISODate("2015-07-08T00:00:00.000Z"), 
                Date(9223372036854775807)
            ]
        ],
        "searchTerms.term" : [ 
            [ 
                "iPhone", 
                "iPhone"
            ]
        ]
    },
    "server" : "...",
    "filterSet" : false,
    "stats" : {
        "type" : "FETCH",
        "works" : 11023,
        "yields" : 1074,
        "unyields" : 1074,
        "invalidates" : 90,
        "advanced" : 275,
        "needTime" : 10746,
        "needFetch" : 1,
        "isEOF" : 1,
        "alreadyHasObj" : 0,
        "forcedFetches" : 0,
        "matchTested" : 0,
        "children" : [ 
            {
                "type" : "IXSCAN",
                "works" : 11022,
                "yields" : 1074,
                "unyields" : 1074,
                "invalidates" : 90,
                "advanced" : 275,
                "needTime" : 10746,
                "needFetch" : 0,
                "isEOF" : 1,
                "keyPattern" : "{ date: 1, searchTerms.term: 1 }",
                "isMultiKey" : 1,
                "boundsVerbose" : "field #0['date']: (new Date(1436313600000), new Date(9223372036854775807)], field #1['searchTerms.term']: [\"iPhone\", \"iPhone\"]",
                "yieldMovedCursor" : 0,
                "dupsTested" : 275,
                "dupsDropped" : 0,
                "seenInvalidated" : 0,
                "matchTested" : 0,
                "keysExamined" : 11022,
                "children" : []
            }
        ]
    }
}

如果这些索引是正确的,我不知道此查询如何运行80秒。系统中有近百万篇文章。这个计数的结果大约是250。

1 个答案:

答案 0 :(得分:0)

这似乎是Sean在大型数据集中的预期行为,其中索引是由于高基数而在日期创建的。 MongoDB现在使用B(alance)-Tree索引,如果列值具有数百万个不同的值(因为日期精确到毫秒并且它们大多数不相同的可能性很高)然后最终它使用Index它没有给出任何好处在这种情况下的索引。 通常,在这种情况下,您必须根据某些日期范围查找数据,但首选的是还有一个列,其中仅包含应用索引的日期部分并在查询条件中使用该数据,这可能有助于大幅提高您的性能..

- $