我有一个包含15万条条目的mongodb集合
文件看起来像这样
{
"_id" : ObjectId("53dc6267a004ccb072e62223"),
"type" : "way",
"id" : 92974485,
"closed" : true,
"tags" : {
"building" : "yes"
},
"attributes" : {
"uid" : "67792",
"timestamp" : "2011-01-02T01:03:18Z",
"id" : "92974485",
"user" : "UncleBob",
"changeset" : "6834391",
"version" : "1"
},
"bb" : {
"top" : 50.1851254,
"bottom" : 50.1847791,
"left" : 8.2829808,
"right" : 8.2837873
},
"area" : 2.792909499972435E-07,
"outers" : [[{
"x" : 8.2830627,
"y" : 50.1847791
}, {
"x" : 8.2837873,
"y" : 50.1850276
}, {
"x" : 8.2837054,
"y" : 50.1851254
}, {
"x" : 8.2829808,
"y" : 50.1848769
}, {
"x" : 8.2830627,
"y" : 50.1847791
}]],
"inners" : [[]]
}
索引就是这样创建的
BasicDBObject boundsIndex = new BasicDBObject();
boundsIndex.put("bb.left", 1);
boundsIndex.put("bb.right", 1);
boundsIndex.put("bb.top", 1);
boundsIndex.put("bb.bottom", 1);
geoCollection.createIndex(boundsIndex);
现在我正在运行像这样的查询
> db.geos.find({ "$and" : [ { "bb.top" : { "$gte" : 50.1800537109375}} , { "bb.bottom" : { "$lte" : 50.185546875}} , { "bb.left" : { "$lte" : 8.294677734375}} , { "bb.right" : { "$gte" : 8.28369140625}} , { "type" : { "$ne" : "node"}}]}).explain();
{
"cursor" : "BtreeCursor bb.left_1_bb.right_1_bb.top_1_bb.bottom_1",
"isMultiKey" : false,
"n" : 82,
"nscannedObjects" : 289,
"nscanned" : 741908,
"nscannedObjectsAllPlans" : 492,
"nscannedAllPlans" : 1004432,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 96,
"nChunkSkips" : 0,
"millis" : 2687,
"indexBounds" : {
"bb.left" : [
[
-Infinity,
8.294677734375
]
],
"bb.right" : [
[
8.28369140625,
Infinity
]
],
"bb.top" : [
[
50.1800537109375,
Infinity
]
],
"bb.bottom" : [
[
-Infinity,
50.185546875
]
]
},
"server" : "wutze-PC:27017",
"filterSet" : false
}
>
在这种情况下返回82个文件。
但查询需要~1800ms。
1800ms是可以忍受的,但是当我同时运行其中5个查询时,它需要大约10000ms。这是不可接受的,我有很大的计划
是否可以提高性能,或者这是我所期望的最高速度?
由于有一个易于使用的索引,我期望更快的结果。
我在使用Intel i5-4670K和8GB ram的Windows上运行mongodb 2.6 ...意味着没有低级系统
EDIT1:查询重新排序
> db.geos.find({ "$and" : [ { "bb.left" : { "$lte" : 8.294677734375}} , { "bb.right" : { "$gte" : 8.28369140625}} , { "bb.top" : { "$gte" : 50.1800537109375}} , { "bb.bottom" : { "$lte" : 50.185546875}}]}).explain()
{
"cursor" : "BtreeCursor bb.left_1_bb.right_1_bb.top_1_bb.bottom_1",
"isMultiKey" : false,
"n" : 289,
"nscannedObjects" : 289,
"nscanned" : 741908,
"nscannedObjectsAllPlans" : 289,
"nscannedAllPlans" : 741908,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 14,
"nChunkSkips" : 0,
"millis" : 2098,
"indexBounds" : {
"bb.left" : [
[
-Infinity,
8.294677734375
]
],
"bb.right" : [
[
8.28369140625,
Infinity
]
],
"bb.top" : [
[
50.1800537109375,
Infinity
]
],
"bb.bottom" : [
[
-Infinity,
50.185546875
]
]
},
"server" : "wutze-PC:27017",
"filterSet" : false
}
>
编辑2:
> db.geos.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"id" : 1
},
"name" : "id_1",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"type" : 1
},
"name" : "type_1",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"closed" : 1
},
"name" : "closed_1",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"tags.natural" : 1
},
"name" : "tags.natural_1",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"tags.landuse" : 1
},
"name" : "tags.landuse_1",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"tags.name" : 1
},
"name" : "tags.name_1",
"ns" : "local.geos"
},
{
"v" : 1,
"key" : {
"bb.left" : 1,
"bb.right" : 1,
"bb.top" : 1,
"bb.bottom" : 1
},
"name" : "bb.left_1_bb.right_1_bb.top_1_bb.bottom_1",
"ns" : "local.geos"
}
]
>
编辑3没有和
> db.geos.find({"bb.left": { "$lte" : 8.294677734375}, "bb.right": { "$gte" : 8.28369140625}, "bb.top": { "$gte" : 50.1800537109375}, "bb.bottom": { "$lte" : 50.185546875}}).explain()
{
"cursor" : "BtreeCursor bb.left_1_bb.right_1_bb.top_1_bb.bottom_1",
"isMultiKey" : false,
"n" : 289,
"nscannedObjects" : 289,
"nscanned" : 741908,
"nscannedObjectsAllPlans" : 289,
"nscannedAllPlans" : 741908,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 13,
"nChunkSkips" : 0,
"millis" : 1866,
"indexBounds" : {
"bb.left" : [
[
-Infinity,
8.294677734375
]
],
"bb.right" : [
[
8.28369140625,
Infinity
]
],
"bb.top" : [
[
50.1800537109375,
Infinity
]
],
"bb.bottom" : [
[
-Infinity,
50.185546875
]
]
},
"server" : "wutze-PC:27017",
"filterSet" : false
}
>
EDIT serverstats
> db.stats()
{
"db" : "local",
"collections" : 5,
"objects" : 15604808,
"avgObjSize" : 571.5683889221834,
"dataSize" : 8919214968,
"storageSize" : 9316446192,
"numExtents" : 29,
"indexes" : 15,
"indexSize" : 6654708032,
"fileSize" : 19251855360,
"nsSizeMB" : 16,
"dataFileVersion" : {
"major" : 4,
"minor" : 5
},
"extentFreeList" : {
"num" : 0,
"totalSize" : 0
},
"ok" : 1
}
>> db.serverStatus()
{
"host" : "wutze-PC",
"version" : "2.6.2",
"process" : "mongod",
"pid" : NumberLong(6328),
"uptime" : 72455,
"uptimeMillis" : NumberLong(72454818),
"uptimeEstimate" : 37621,
"localTime" : ISODate("2014-08-03T17:17:39.439Z"),
"asserts" : {
"regular" : 0,
"warning" : 0,
"msg" : 0,
"user" : 0,
"rollovers" : 0
},
"backgroundFlushing" : {
"flushes" : 628,
"total_ms" : 2828685,
"average_ms" : 4504.275477707007,
"last_ms" : 40,
"last_finished" : ISODate("2014-08-03T17:17:22.560Z")
},
"connections" : {
"current" : 2,
"available" : 999998,
"totalCreated" : NumberLong(22)
},
"cursors" : {
"note" : "deprecated, use server status metrics",
"clientCursors_size" : 0,
"totalOpen" : 0,
"pinned" : 0,
"totalNoTimeout" : 0,
"timedOut" : 0
},
"dur" : {
"commits" : 30,
"journaledMB" : 0,
"writeToDataFilesMB" : 0,
"compression" : 0,
"commitsInWriteLock" : 0,
"earlyCommits" : 0,
"timeMs" : {
"dt" : 3060,
"prepLogBuffer" : 0,
"writeToJournal" : 0,
"writeToDataFiles" : 0,
"remapPrivateView" : 0
}
},
"extra_info" : {
"note" : "fields vary by platform",
"page_faults" : 129486579,
"usagePageFileMB" : 158,
"totalPageFileMB" : 16162,
"availPageFileMB" : 10378,
"ramMB" : 8081
},
"globalLock" : {
"totalTime" : NumberLong("72454821000"),
"lockTime" : NumberLong(1502088883),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 0,
"readers" : 0,
"writers" : 0
}
},
"indexCounters" : {
"accesses" : 575367889,
"hits" : 575367889,
"misses" : 0,
"resets" : 0,
"missRatio" : 0
},
"locks" : {
"." : {
"timeLockedMicros" : {
"R" : NumberLong(52755051),
"W" : NumberLong(1502088883)
},
"timeAcquiringMicros" : {
"R" : NumberLong(247643851),
"W" : NumberLong(42199701)
}
},
"admin" : {
"timeLockedMicros" : {
"r" : NumberLong(369986),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(864),
"w" : NumberLong(0)
}
},
"local" : {
"timeLockedMicros" : {
"r" : NumberLong(1638453258),
"w" : NumberLong("3237777167")
},
"timeAcquiringMicros" : {
"r" : NumberLong("2804943595"),
"w" : NumberLong(739358049)
}
},
"test" : {
"timeLockedMicros" : {
"r" : NumberLong(11863),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(821),
"w" : NumberLong(0)
}
}
},
"network" : {
"bytesIn" : 8620819599,
"bytesOut" : 7663424729,
"numRequests" : 17320018
},
"opcounters" : {
"insert" : 15604773,
"query" : 17290096,
"update" : 0,
"delete" : 0,
"getmore" : 4,
"command" : 16188
},
"opcountersRepl" : {
"insert" : 0,
"query" : 0,
"update" : 0,
"delete" : 0,
"getmore" : 0,
"command" : 0
},
"recordStats" : {
"accessesNotInMemory" : 3448647,
"pageFaultExceptionsThrown" : 1689,
"admin" : {
"accessesNotInMemory" : 0,
"pageFaultExceptionsThrown" : 0
},
"local" : {
"accessesNotInMemory" : 3448647,
"pageFaultExceptionsThrown" : 1689
},
"test" : {
"accessesNotInMemory" : 0,
"pageFaultExceptionsThrown" : 0
}
},
"writeBacksQueued" : false,
"mem" : {
"bits" : 64,
"resident" : 172,
"virtual" : 36932,
"supported" : true,
"mapped" : 18376,
"mappedWithJournal" : 36752
},
"metrics" : {
"cursor" : {
"timedOut" : NumberLong(0),
"open" : {
"noTimeout" : NumberLong(0),
"pinned" : NumberLong(0),
"total" : NumberLong(0)
}
},
"document" : {
"deleted" : NumberLong(0),
"inserted" : NumberLong(15604773),
"returned" : NumberLong(17275473),
"updated" : NumberLong(0)
},
"getLastError" : {
"wtime" : {
"num" : 0,
"totalMillis" : 0
},
"wtimeouts" : NumberLong(0)
},
"operation" : {
"fastmod" : NumberLong(0),
"idhack" : NumberLong(0),
"scanAndOrder" : NumberLong(0)
},
"queryExecutor" : {
"scanned" : NumberLong(5798761),
"scannedObjects" : NumberLong(1601)
},
"record" : {
"moves" : NumberLong(0)
},
"repl" : {
"apply" : {
"batches" : {
"num" : 0,
"totalMillis" : 0
},
"ops" : NumberLong(0)
},
"buffer" : {
"count" : NumberLong(0),
"maxSizeBytes" : 268435456,
"sizeBytes" : NumberLong(0)
},
"network" : {
"bytes" : NumberLong(0),
"getmores" : {
"num" : 0,
"totalMillis" : 0
},
"ops" : NumberLong(0),
"readersCreated" : NumberLong(0)
},
"preload" : {
"docs" : {
"num" : 0,
"totalMillis" : 0
},
"indexes" : {
"num" : 0,
"totalMillis" : 0
}
}
},
"storage" : {
"freelist" : {
"search" : {
"bucketExhausted" : NumberLong(0),
"requests" : NumberLong(16418927),
"scanned" : NumberLong(32837623)
}
}
},
"ttl" : {
"deletedDocuments" : NumberLong(0),
"passes" : NumberLong(626)
}
},
"ok" : 1
}
>
答案 0 :(得分:1)
有些注意事项:
使用投影和复合索引创建覆盖查询可能会大大加快搜索速度。使用包含_id字段的覆盖查询和随后的doc(s)检索的两步检索也可能是有效的方法。要创建的索引是DB.geos.ensureIndex({"bb":"2d","_id":1})
(当然,适应边界框的存储),相应的查询将是db.geos.find({"bb":{$geoWithin:{$box: [[ xOfBottomLeft, yOfBottomLeft],[xOfTopRight, yOfTopRight]]}}},{"bb":1})
。投影应使其成为覆盖查询,默认情况下返回_id
字段。现在,您可以使用$or
运算符迭代结果集或在一个查询中获取完整的文档。但是,使用2d查询可以加快搜索速度,使您根本不必使用投影,并使用第一个查询检索文档。
编辑:您真的不应该使用本地数据库来存储您的馆藏。本地数据库不会复制到副本集中(因此名称为local)。我不确定它是否也可以分片。