为什么我的索引只在这个Mongo查询中使用?

时间:2011-11-18 12:01:40

标签: mongodb indexing mongodb-.net-driver

我认为在Mongo中我认为是一个非常简单,直接的查询,并创建了索引:

{ "Ended" : 1, "EndDate" -1 }

然而,当我对它运行一个简单的查询时,它似乎识别出索引,但它仍在扫描大量对象以检索数据。这是我的查询和解释结果:

PRIMARY> db.listing.find({ "Ended" : { "$ne" : true }, "EndDate" : { "$lte" : ISODate("2011-11-18T00:47:40.638Z") } }).explain();
{
        "cursor" : "BtreeCursor Ended_1_EndDate_-1 multi",
        "nscanned" : 24508585,
        "nscannedObjects" : 24508583,
        "n" : 24508583,
        "millis" : 108323,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "Ended" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                true
                        ],
                        [
                                true,
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "EndDate" : [
                        [
                                ISODate("2011-11-18T00:47:40.638Z"),
                                true
                        ]
                ]
        }
}

任何明显的想法我做错了什么?谢谢!

3 个答案:

答案 0 :(得分:4)

使用$ ne或$ nin查询的索引不是很好。你最好用

db.listing.find({ "Ended" : false , "EndDate" : { "$lte" : ISODate("2011-11-18T00:47:40.638Z") } })

这里的不同之处在于,如果没有“已结束”字段,或者“结束”字段为空或其他类型,您将不再获取文档。

Indexing Advice & FAQ - MongDOB

答案 1 :(得分:2)

n字段表示您的查询匹配24.5M文档,与nscannedObjects相同,这是正常行为。如果您不需要所有24.5M匹配的文档,则应在查询中添加其他条件。

我也看到您正在使用EndedDate: {$ne: true}。虽然这会有效,但它会比EndedDate: false慢,所以如果该字段可能只有truefalse,那么最好不要使用后者。

答案 2 :(得分:0)

它不会仅使用索引,因为您将通过该查询检索未编制索引的其他字段。

过去你的所有文件都有EndDate吗?当您使用当前日期的LTE时,它仍将扫描当前日期之前的所有索引项。它只扫描索引,它比扫描整个文档更快。

如果您查询日期范围,则会看到扫描对象的数量下降。