【发布时间】:2013-04-13 11:41:14
【问题描述】:
当输入数据是单个值并且集合数据包含最小/最大范围时,在 Mongo 中查找数据的最有效方法是什么?例如:
record = { min: number, max: number, payload }
需要为记录的最小/最大范围内的数字查找记录。范围从不相交。范围的大小无法预测。
该集合中有大约 600 万条记录。如果我解压缩范围(范围内的每个值都有记录),我会查看大约 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"
}
【问题讨论】:
-
那是很长一段时间 - 你有多少内存?这是什么版本的MongoDB?你能在查询运行时运行 mongostat 并捕获它的输出吗?
-
@AsyaKamsky 正如 Leopd 所说的那样,这并不意外,数据库必须搜索大量记录(查看解释输出)。除非 MongoDB 支持几何索引,否则这只是生活中的事实,否则我必须使用一些技巧(现在评估他的):)
-
它确实支持二维索引,但它们的语义是专门针对地理的。如果您想出一些聪明的应用程序,它仍然可能对您有用。
-
二维索引可以非常有效地用于重叠范围查询 - 它不必是实际坐标,只需开始、结束对(例如)
-
在这种情况下我需要一个 1d 索引 :) 使用 LineSegment(我可以为此重新调整 2d 的用途,将第二个坐标锁定为 0)。然后我会调用 geoNear() 来找到离我的点最近的(距离 0)段。 @AsyaKamsky 让我知道你是否想让我尝试一下。
标签: mongodb optimization database