首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MongoDB中查询子对象时未使用索引

在MongoDB中查询子对象时未使用索引
EN

Stack Overflow用户
提问于 2011-02-06 23:54:50
回答 2查看 1.1K关注 0票数 0

我在一个(访问者)的子对象中记录站点使用事件。以下是数据结构的基本示例:

代码语言:javascript
复制
{ "_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上搜索时,该索引不会被使用:

代码语言:javascript
复制
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()

代码语言:javascript
复制
{
  "ns" : "tracking.visitors",
  "unique" : false,
  "key" : {
     "evs.s" : 1
  },
  "name" : "evs.s_1",
  "v" : 0
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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语句。一旦找到有限制的文档,这将停止扫描索引。

票数 2
EN

Stack Overflow用户

发布于 2011-02-07 00:04:18

"cursor“:"BtreeCursor evs.s_1”

表示使用了索引。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4914336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档