首页 文章

MongoDb使用索引缓慢查询

提问于
浏览
0

我们有一个包含一些数据的MongoDB NoSQL数据库 . 目前,DB包含10M行 . 默认的_id字段用作主键 . 我们的集合有三个变量:

  • _id

  • 时间戳(索引:1)

  • Variable1(索引:1,带时间戳的CompoundIndex)

  • 变量2

  • 变量3

我们希望有一个组合Timestamp和variable1的查询 . 我们在Timestamp和Variable1上有一个索引 . 另外,即使这对范围查询不正确,我们在(Timestamp,Variable1)上有一个复合索引 .

不,当我们遇到如下问题时,性能非常差(约1分钟执行时间) .

示例查询:

db.getCollection('XXX').find({$and:[
{timestamp:{$lte:1424195749000}},
{timestamp:{$gte:1424195649000}},
{Variable1:1}
]})

仅使用Variable1字段的查询运行大约(100ms) .

getIndexes():

{
    "0" : {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "XXXXXX_DB.XXXData"
    },
    "1" : {
        "v" : 1,
        "key" : {
            "timestamp" : 1.0000000000000000
        },
        "name" : "timestamp_1",
        "ns" : "XXXXXX_DB.XXXData"
    },
    "2" : {
        "v" : 1,
        "key" : {
            "timestamp" : -1.0000000000000000
        },
        "name" : "timestamp_-1",
        "ns" : "XXXXXX_DB.XXXData"
    },
    "3" : {
        "v" : 1,
        "key" : {
            "variable1" : 1.0000000000000000
        },
        "name" : "variable1_1",
        "ns" : "XXXXXX_DB.XXXData"
    },
    "4" : {
        "v" : 1,
        "key" : {
            "timestamp" : 1.0000000000000000,
            "variable1" : 1.0000000000000000
        },
        "name" : "timestamp_1_variable1_1",
        "ns" : "XXXXXX_DB.XXXData"
    }
}

1 回答

  • 3

    您需要 { Variable1: 1, timestamp: 1 } 上的索引来加速该查询(使用大写 V - 您使用“ V ariable1 " in the query but your index seems to be on " v ariable1”)


    鉴于您的查询:

    db.getCollection('XXX').find({$and:[
      {timestamp:{$lte:1424195749000}},
      {timestamp:{$gte:1424195649000}},
      {Variable1:1}
    ]})
    

    在这里,优化器将在 Variable1 上看到您具有相等性 . 所以这个字段是"most limiting" . 因此优化器将选择一个将其作为前缀的索引 . { Variable: 1} 不应该太糟糕 . 但是 { Variable: 1, timestamp: 1} 会更好 .

    请注意,您有多余的索引:

    • {timestamp:-1} 不要添加太多 {timestamp:1}

    • {Variable1: 1} 如果你有 {Variable1: 1, timestamp: 1} 就没用了
      (因为前者是后者的前缀)

    • {timestamp: 1} 如果你有 {timestamp: 1, Variable1: 1} 就没用了
      (因为前者是后者的前缀)

相关问题