【问题标题】:MongoDb query and indexOnly=falseMongoDb 查询和 indexOnly=false
【发布时间】:2014-03-22 18:11:09
【问题描述】:

执行下一个查询(字段:{_id: 1}):

{ 
  "namespace": "default", 
  "active": true, 
  "searchable": true, 
  "type": "H",
  "keywords.extended": /^a/, 
}

在包含 2.200.000 个文档(匹配命名空间 200.000 个文档)和文档的集合中:

{
  "active" : true,
  "keywords" : {
    "extended" : ["lorem", "ipsum", "sit", "amet"]
  },
  "namespace" : "rsvcom",
  "searchable" : true,
  "type" : "H"
}

带索引:

{ 
  "namespace": 1, 
  "active": 1, 
  "searchable": 1, 
  "type": 1, 
  "keywords.extended": 1 
}

我永远不会让 indexOnly=true 执行“查找”或“计数”。

  1. 是否可以优化我查询此集合的方式?
  2. 是否可以仅使用索引并花费不到 1 毫秒的时间进行计数?

这是限制为 5000 的解释:

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    你不会得到索引这里只解释三个原因:

    1. 您没有指定只返回索引中的字段。覆盖索引查询必须有一个投影,以便索引可以用于过滤和取回查询的值。

    2. 您正在使用多键索引。您不能使用 indexOnly 查询,因为 MongoDB 多键索引不包含有关哪个字段是数组的信息,因此需要进行文档查找。

    3. 您在文档/查询中嵌入了字段。 MongoDB 无法从索引中确定嵌入字段是子文档还是数组元素,因此它必须自己查找文档。

    这不是一个特别快速的查询还有另一个原因 - 您正在使用正则表达式。虽然左锚正则表达式将能够使用索引(其中正则表达式是最后一个字段),但它不会像相等查询那样快(就像范围查询不如相等查询高效一样) .

    【讨论】:

      【解决方案2】:

      投影结果以仅返回属于索引的字段。

      只有当您进行投影以从结果中消除所有不属于索引的字段时,您才会得到覆盖索引 indexOnly=true;在您的情况下,例如 subdoc 字段(关键字)。说明:当查询的结果可以完全由索引决定时,得到indexOnly=true,表示查询返回的所有数据都可以完全只用索引来计算。

      在您的特殊情况下,有两件事可能会阻止它: - 如果不投影,mongo 不会预先知道子文档中除了数组之外没有其他字段;无模式数据库。 - 即使 mongo new 没有其他字段,我不确定从索引计算数组字段是否会比从数据库中选择完整的文档更便宜(在计算方面)。反正我不知道mongo在那种情况下是怎么做的。

      【讨论】:

        【解决方案3】:

        编辑: 正如 @Sammaye 在下面的评论中所指出的,覆盖索引不适用于虚线字段,如 JIRA Ticket 中所述


        那是因为,查询可能在结果中也得到了_id 运算符。尝试修改您的查找查询以包含投影条件以在结果中明确包含您想要的字段并禁止_id 字段:

        db.collection.find(
        { 
          "namespace": "default", 
          "active": true, 
          "searchable": true, 
          "type": "H",
          "keywords.extended": /^a/ 
        },
        { 
          _id : 0,
          "namespace": 1, 
          "active": 1, 
          "searchable": 1, 
          "type": 1,
          "keywords.extended": 1 
        }
        )
        

        【讨论】:

        • 你是对的。很抱歉在发布答案之前没有进行完整的研究。我会删除它。
        • 只需修改它以包含 JIRA
        • 您应该将 JIRA 作为单独的答案发布。
        • 无论如何这都是错误的投影。要获得涵盖的索引查询,您必须指定要返回的字段。没关系,因为这是一个多键索引。
        • @AsyaKamsky,谢谢!我的意思是复制 n 粘贴查询条件中的字段,但错过了。
        猜你喜欢
        • 2014-03-13
        • 2013-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-01
        • 2013-09-28
        • 1970-01-01
        相关资源
        最近更新 更多