查询在mongodb中使用单个和多个索引的性能

时间:2017-09-21 09:20:49

标签: mongodb mongodb-query

您好我使用此

创建了集合索引

首先:

db.device_data.createIndex({'device_id': 1});

第二

db.device_data.createIndex({'device_id': 1,'slave_id':1});

现在当我做 db.device_data.getIndexes()时,我得到了这些

 {
        "v": 2,
        "key": {
            "_id": 1
        },
        "name": "_id_",
        "ns": "node-rest-auth-2.device_data"
    }, {
        "v": 2,
        "key": {
            "device_id": 1,
            "slave_id": 1
        },
        "name": "device_id_1_site_id_1_slave_id_1",
        "ns": "node-rest-auth-2.device_data",
        "background": true
    }, {

        "v": 2,
        "key": {
            "device_id": 1
        },
        "name": "device_id_1",
        "ns": "node-rest-auth-2.device_data"
    }

有人可以解释第二和第三个关键对象。 device_id的单个索引与同时具有device_id和slave_id的索引有何不同。

更新用例

我在一个集合中总共有300,000个文档,我试图一次性获取30,000个文档。没有任何索引(除了_id),使用MEAN堆栈需要20秒,在索引时我预计会有一些加速,但没有显着的变化。

1 个答案:

答案 0 :(得分:2)

第二个索引:device_id_1_site_id_1_slave_id_1是复合索引,此索引包含对多个字段的引用。如果您的常见查询用例包括一起这两个字段,那么可能会定义这样的索引。更多详情in the docs

第三个索引:device_id_1是单个字段索引,此索引包含对单个字段的引用。如果您的常见查询用例包含此字段,则可能定义这样的索引。更多详情in the docs

您的问题中可能缺少某些子文字,可能需要解释为什么您对单字段和复合索引之间的差异感兴趣。如果这种兴趣纯粹是理论上的,那么我建议你阅读我上面链接的文档。如果这种兴趣是实际的 - 也许你正在调查查询性能问题 - 那么我建议更新问题以使这些问题清楚,以便任何答案都可以解决它们。

更新1:以回答此评论:“如果查询可以同时包含多个符号,那该怎么办”

此时您可能希望阅读index intersection in MongoDB

更一般地说,在考虑索引策略时,您通常需要...

  • 了解您的阅读模式:正在使用哪些属性(和运算符),正在使用哪些属性组合
  • 了解您的非功能需求;您的系统是否已满足已知读取用例的缩短时间要求
  • 了解索引的成本;他们在写入时有一些成本,并且还会产生存储成本

...然后从最简单的索引策略开始,使用profiling和/或explain查看您的查询行为,然后进行调整和重新测试等。

鉴于您目前提供的详细信息,您的起始位置可能是删除此索引:device_id_1并使用profiling / explain查看此索引:device_id_1_site_id_1_slave_id_1是否对您的用例具有足够的选择性。但是,这个建议是基于不完整的信息,因为我对你的非功能性要求一无所知,我对你对索引成本的容忍度一无所知等等。所以,我建议你遵循这个方法

  • 了解您的要求
  • 了解MongoDB索引(通过阅读我上面链接的文档)
  • 测试您的系统并使用分析/解释来了解它在幕后的行为
  • 调整并重新测试
  • 重复直至满足您的要求
  • 记录读取端性能的指标,以便您可以留意任何降级并主动进一步调整以解决性能下降问题