我在一个(访问者)的子对象中记录站点使用事件。以下是数据结构的基本示例:
{ "_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
}发布于 2011-02-07 00:06:57
您的查询实际上使用了一个索引,如explain输出中的游标类型("BtreeCursor evs.s_1")所示。如果您没有使用an索引,那么它将是"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().count();
来验证这一点。
您可以执行以下几项操作来加速此过程:
1)您可以使用具有更多不同值的不同索引。这将减少每个查询的搜索空间。
2)您可以在查询中添加limit语句。一旦找到有限制的文档,这将停止扫描索引。
发布于 2011-02-07 00:04:18
"cursor“:"BtreeCursor evs.s_1”
表示使用了索引。
https://stackoverflow.com/questions/4914336
复制相似问题