Den*_*nis 6 mongodb mongodb-query
我有一个网页,它使用MongoDB存储和检索各种测量.突然间,在某些时候,我的网页变得如此迟钝,变得无法使用.事实证明,我的数据库是罪魁祸首.
我搜索并没有找到任何解决我的问题的方法,我道歉,因为我对MongoDB很新,并且此刻拉我的头发.
我正在使用的MongoDB版本是2.4.6,在具有20GB RAM的VM Machine上运行,它运行Ubuntu服务器12.04.没有复制或分片设置.
首先,我将我的分析级别设置为2,它显示了最慢的查询:
db.system.profile.find().sort({"millis":-1}).limit(1).pretty()
{
"op" : "query",
"ns" : "station.measurement",
"query" : {
"$query" : {
"e" : {
"$gte" : 0
},
"id" : "180"
},
"$orderby" : {
"t" : -1
}
},
"ntoreturn" : 1,
"ntoskip" : 0,
"nscanned" : 3295221,
"keyUpdates" : 0,
"numYield" : 6,
"lockStats" : {
"timeLockedMicros" : {
"r" : NumberLong(12184722),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(5636351),
"w" : NumberLong(5)
}
},
"nreturned" : 0,
"responseLength" : 20,
"millis" : 6549,
"ts" : ISODate("2015-03-16T08:57:07.772Z"),
"client" : "127.0.0.1",
"allUsers" : [ ],
"user" : ""
}
Run Code Online (Sandbox Code Playgroud)
我使用.explain()运行该特定查询,看起来像它应该使用索引,但它需要太长时间.我也在我的另一个服务器上运行了相同的查询,这个服务器在一秒钟内就像一个冠军一样掏出结果.
> db.measurement.find({"id":"180", "e":{$gte:0}}).sort({"t":-1}).explain()
{
"cursor" : "BtreeCursor id_1_t_-1_e_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 660385,
"nscannedObjectsAllPlans" : 1981098,
"nscannedAllPlans" : 3301849,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 7,
"nChunkSkips" : 0,
"millis" : 7243,
"indexBounds" : {
"id" : [
[
"180",
"180"
]
],
"t" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"e" : [
[
0,
1.7976931348623157e+308
]
]
},
"server" : "station:27017"
}
Run Code Online (Sandbox Code Playgroud)
接下来,我查看了测量集合的索引,它对我来说很好看:
> db.measurement.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "station.measurement",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"t" : 1
},
"ns" : "station.measurement",
"name" : "t_1"
},
{
"v" : 1,
"key" : {
"id" : 1,
"d" : 1,
"_id" : -1
},
"ns" : "station.measurement",
"name" : "id_1_d_1__id_-1"
},
{
"v" : 1,
"key" : {
"id" : 1,
"t" : -1,
"e" : 1
},
"ns" : "station.measurement",
"name" : "id_1_t_-1_e_1"
},
{
"v" : 1,
"key" : {
"id" : 1,
"t" : -1,
"e" : -1
},
"ns" : "station.measurement",
"name" : "id_1_t_-1_e_-1"
}
]
Run Code Online (Sandbox Code Playgroud)
这里还有我收藏的其他信息:
> db.measurement.stats()
{
"ns" : "station.measurement",
"count" : 157835456,
"size" : 22377799512,
"avgObjSize" : 141.77929395027692,
"storageSize" : 26476834672,
"numExtents" : 33,
"nindexes" : 5,
"lastExtentSize" : 2146426864,
"paddingFactor" : 1.0000000000028617,
"systemFlags" : 0,
"userFlags" : 0,
"totalIndexSize" : 30996614096,
"indexSizes" : {
"_id_" : 6104250656,
"t_1" : 3971369360,
"id_1_d_1__id_-1" : 8397896640,
"id_1_t_-1_e_1" : 6261548720,
"id_1_t_-1_e_-1" : 6261548720
},
"ok" : 1
}
Run Code Online (Sandbox Code Playgroud)
我尝试添加新索引,修复整个数据库,重新索引.我究竟做错了什么?我真的很感激任何帮助,因为我拼命想法.
更新1:
我按照Neil Lunn的建议添加了两个索引,其中一些查询速度更快:
{
"v" : 1,
"key" : {
"id" : 1,
"e" : 1,
"t" : -1
},
"ns" : "station.measurement",
"name" : "id_1_e_1_t_-1",
"background" : true
},
{
"v" : 1,
"key" : {
"id" : 1,
"e" : -1,
"t" : -1
},
"ns" : "station.measurement",
"name" : "id_1_e_-1_t_-1",
"background" : true
}
Run Code Online (Sandbox Code Playgroud)
我得到的结果很有趣(不确定它们是否相关)
接下来的两个查询仅与"id"不同.请注意,每个查询使用不同的索引,为什么?我应该删除较旧的吗?
> db.measurement.find({"id":"119", "e":{$gte:0}}).sort({"t":-1}).explain()
{
"cursor" : "BtreeCursor id_1_t_-1_e_1",
"isMultiKey" : false,
"n" : 840747,
"nscannedObjects" : 840747,
"nscanned" : 1047044,
"nscannedObjectsAllPlans" : 1056722,
"nscannedAllPlans" : 1311344,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 4,
"nChunkSkips" : 0,
"millis" : 3730,
"indexBounds" : {
"id" : [
[
"119",
"119"
]
],
"t" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"e" : [
[
0,
1.7976931348623157e+308
]
]
},
"server" : "station:27017"
}
> db.measurement.find({"id":"180", "e":{$gte:0}}).sort({"t":-1}).explain()
{
"cursor" : "BtreeCursor id_1_e_1_t_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 45,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"id" : [
[
"180",
"180"
]
],
"e" : [
[
0,
1.7976931348623157e+308
]
],
"t" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
},
"server" : "station:27017"
}
Run Code Online (Sandbox Code Playgroud)
问题可能在别的地方吗?什么可能导致突然"缓慢"?我还有其他几个集合,查询突然变慢了.
哦,还有一件事.在我拥有的其他服务器上,索引与添加新索引之前的索引相同.是的,收集有点小,但速度要快几倍.
然后这里的重点是索引和查询排序选择。
如果您查看之前的输出,.explain()
您会发现表达式中的“t”元素有一个“最小/最大”范围。通过“将其移至求值的末尾”,您可以允许对整体表达式更重要的其他过滤元素(在扫描基本上“所有内容”中的“t”之前,确定“e”的不太可能的匹配是主要因素) 。
这有点像 DBA,但在 NoSQL 世界中,我确实相信这会成为程序员的问题。
您本质上需要沿着选定的键构建“最短匹配路径”,以获得最有效的扫描。这就是为什么改变后的结果执行得更快。
归档时间: |
|
查看次数: |
2641 次 |
最近记录: |