MongoDb使用索引缓慢查询

时间:2015-05-29 07:52:05

标签: mongodb database nosql

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

  • _id
  • 时间戳(索引:1)
  • Variable1(索引:1,带时间戳的CompoundIndex)
  • 变量
  • Variable3

我们希望有一个组合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 个答案:

答案 0 :(得分:3)

您需要{ Variable1: 1, timestamp: 1 }上的索引才能加快查询速度(使用大写 V - 您使用“ V ariable1“在查询中,但您的索引似乎在” v ariable1“)

鉴于您的疑问:

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

此处,优化程序会在Variable1上看到您有相等。所以这个领域是“最有限的”。因此优化器将选择一个将其作为前缀的索引。 { Variable: 1}不应该太糟糕。但{ Variable: 1, timestamp: 1}会更好。

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

  • {timestamp:-1}不会对{timestamp:1}
  • 添加太多内容
  • {Variable1: 1}如果你有{Variable1: 1, timestamp: 1}˙(前者是后者的前缀),则无用。
  • {timestamp: 1}如果你有{timestamp: 1, Variable1: 1}˙(前者是后者的前缀),则无用。