我们有一个包含一些数据的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 回答
您需要
{ Variable1: 1, timestamp: 1 }
上的索引来加速该查询(使用大写 V - 您使用“ V ariable1 " in the query but your index seems to be on " v ariable1”)鉴于您的查询:
在这里,优化器将在
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}
就没用了(因为前者是后者的前缀)