mongo 查询不会触发复合索引

Posted

技术标签:

【中文标题】mongo 查询不会触发复合索引【英文标题】:mongo query does not trigger compound index 【发布时间】:2022-01-22 07:37:18 【问题描述】:

我有成千上万这样的文件:

    
  "field_id" : "abcd",
  "aField" : 0,
  "parentList": [
      
        "field": "value1",
        "list": ["element1,element2"]
      
      , 
      
        "field": "value2",
        "list": ["element1, element3"]
      
  ]

(这是我的数据库中更大文档的过度简化版本,包含更多字段。数据库包含数百万个文档)。 这是我要用于计数执行的过滤器:

 'parentList.0.list': 
          '$in': 
            [ 'element1',
              'element2',
              'element3',
              'element4' 
              ] 
            ,
        aField:  '$ne': 1 ,
        field_id:  '$in': [ 'abcd' ]  

我想做的是创建一个这样的索引:

"field_id" : 1, "parentList.list" :1, "aField" : 1

并让查询使用它。但mongo实际上忽略了它。相反,mongo 正在使用另一个索引,即

"field_id":1, "anotherField":1

执行统计显示这个阶段:

    IXSCAN 对 "field_id":1, "anotherField":1 索引,产生 500k 个keysExamined,即 field_id = 'abcd' 的 500k 个文档 获取过滤器的其余部分,返回 20k 作为计数

当然,如果 mongo 使用了正确的索引,我希望它已经从 IXSCAN 检索到 20k 文档,或者至少是更接近的数字。

我只是不明白为什么 mongo 不使用该索引。我还尝试更改索引中字段的顺序,但没有成功。 我正在使用 Mongo 4.4.6

【问题讨论】:

【参考方案1】:

Mongo 有时会使用错误的索引,我建议您阅读我的回答 here,它解释了为什么会发生这种情况。

为了“修复”您应该使用$hint 的行为,它将强制 Mongo 使用您指定的特定索引。

【讨论】:

实际上,如果我使用hint,它甚至会返回比以前更多的keysExamined。像 520k 而不是 500k。好奇怪 看来 Mongo 正在为这项工作选择“最佳”现有索引。如果您愿意,我可以推荐一些更改以提高性能【参考方案2】:

这个索引

"field_id":1, "anotherField":1

适用于针对您的数据库的大多数查询?

根据我的经验,MongoDB 通常会选择一个非常通用的索引,即使有时更具体的索引会更好。我通过使索引更具体地针对其用途(并删除“包罗万象”的索引)来解决此问题。我不知道这是否适用于您的用例,因为不知道所选索引的原因。

【讨论】:

【参考方案3】:

已解决

所以这实际上很容易解决。 MongoDB Compass 不允许我在数组的某个位置(在本例中为 parentList.0.list)创建索引,因为当我尝试插入它时,它会自动将其替换为 parentList.list。 最终,我发现如果在 shell 中完成,数组某个位置的索引实际上是可行的。所以我在 parentList.0.list 上创建了索引并且索引工作正常。 而已。希望这对其他人也有帮助。

【讨论】:

以上是关于mongo 查询不会触发复合索引的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB索引

如果我在一个字段上同时具有简单索引和复合索引,那么在包含该字段的查询中使用哪一个?

索引优化

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

数组字段上的唯一复合索引

复合索引顺序 MySQL 查询