2011-02-06 96 views
0

我在(访问者)的子对象中记录网站使用事件。这里是数据结构的基本例子:在MongoDB中查询子对象不使用索引

{ "_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

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

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

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

你可能会比较

db.visits.find的输出({evs.s:0})计数();

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

db.visits.find()。count();

来验证这一点。

有几件事情可以做,以加快这:

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

2)您可以为查询添加限制语句。一旦发现限制文件,这将停止扫描索引。

+0

Ahhhhh是的你的权利,没有真正的方法来有效地索引10,000 0的。限制大大加快查询速度,谢谢! – Lerchmo 2011-02-06 16:11:13

0

“光标”: “BtreeCursor evs.s_1”

意味着索引使用