我们有一个包含一些数据的MongoDB NoSQL数据库。目前,DB包含10M行。默认的_id字段用作主键。 我们的集合有三个变量:
我们希望有一个组合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"
}
}
答案 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}
˙(前者是后者的前缀),则无用。