当输入数据是单个值且集合数据包含最小/最大范围时,在Mongo中查找数据的最有效方法是什么? E.g:
record = { min: number, max: number, payload }
需要找到一个在记录的最小/最大范围内的数字的记录。范围永远不会相交。关于范围的大小没有可预测性。
该集合中有大约6M条记录。如果我解压缩范围(在范围内有每个值的记录),我会查看大约4B个记录。
我已经创建了{min:1,max:1}
的复合索引,但尝试使用:
db.block.find({min:{$lte:value},max:{$gte:value})
......需要几到几十秒的时间。以下是explain()
和getIndexes()
的输出。有什么技巧可以让搜索执行得更快吗?
NJmongo:PRIMARY> db.block.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "mispot.block",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"min" : 1,
"max" : 1
},
"ns" : "mispot.block",
"name" : "min_1_max_1"
}
]
NJmongo:PRIMARY> db.block.find({max:{$gte:1135194602},min:{$lte:1135194602}}).explain()
{
"cursor" : "BtreeCursor min_1_max_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1199049,
"nscannedObjectsAllPlans" : 1199050,
"nscannedAllPlans" : 2398098,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 7534,
"nChunkSkips" : 0,
"millis" : 5060,
"indexBounds" : {
"min" : [
[
-1.7976931348623157e+308,
1135194602
]
],
"max" : [
[
1135194602,
1.7976931348623157e+308
]
]
},
"server" : "ccc:27017"
}
答案 0 :(得分:1)
如果block
记录的范围从不重叠,那么您可以通过以下方式更快地完成此任务:
db.block.find({min:{$lte:value}}).sort({min:-1}).limit(1)
此查询几乎会立即返回,因为它可以在索引中通过简单查找找到记录。
您运行的查询速度很慢,因为这两个子句都匹配数百万条必须合并的记录。实际上,我认为您的查询在min
和max
上使用单独的索引会运行得更快(可能更快),因为复合索引的max
部分只能用于给定{ {1}} - 不要搜索具有特定min
的文档。