在MongoDB中查询子对象不使用索引

时间:2011-02-06 15:54:50

标签: mongodb indexing

我正在(访客)的子对象中记录网站使用事件。这是数据结构的基本示例:

{ "_id" : ObjectId("4d4c695794b332a0740009bd"), "evs" : [
    {
            "ev" : "Visit Home Page",
            "d" : 1,
            "s" : 1
    },
    {
            "ev" : "Buy Product",
            "d" : "110.10",
            "upc" : 1234,
            "s" : 1
    },
    {
            "ev" : "Sign up to newsletter",
            "d" : "1",
            "s" : 1
    }
]}

我有'evs.s'的索引,但是当我搜索evs.s时,不使用索引:

db.visitors.find({'evs.s':0}).explain()
{
    "cursor" : "BtreeCursor evs.s_1",
    "nscanned" : 33361,
    "nscannedObjects" : 33361,
    "n" : 33361,
    "millis" : 311,
    "nYields" : 105,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
            "evs.s" : [
                    [
                            0,
                            0
                    ]
            ]
    }
}

该查询需要311毫秒并扫描每个对象。

这是索引:db.visitors.getIndexes()

{
  "ns" : "tracking.visitors",
  "unique" : false,
  "key" : {
     "evs.s" : 1
  },
  "name" : "evs.s_1",
  "v" : 0
}

2 个答案:

答案 0 :(得分:2)

您的查询实际上正在使用索引,如解释输出中的游标类型所示(“BtreeCursor evs.s_1”)。如果你没有使用索引,它将是“BasicCursor”。

从您的输入数据看,evs.s可能不是一个非常有效的索引键。如果evs.s的所有值都是1或0,则索引将始终匹配大量匹配项。

我的猜测是你的查询没有进行全表扫描,但实际上你的索引中存在许多值为evs.s = 0的记录。

您可以比较

的输出

db.visits.find({evs.s:0})。count();

db.visits.find({evs.s:1})。count();

db.visits.find()计数();

验证这一点。

您可以采取以下措施加快速度:

1)您可以使用具有更多不同值的其他索引。这将减少每个查询的搜索空间。

2)您可以在查询中添加限制语句。一旦找到限制文档,这将停止扫描索引。

答案 1 :(得分:0)

“cursor”:“BtreeCursor evs.s_1”

表示使用索引