Mongodb 按ISODate排序的聚合查询性能
我有这种简单的聚合查询Mongodb 按ISODate排序的聚合查询性能,mongodb,database-performance,isodate,Mongodb,Database Performance,Isodate,我有这种简单的聚合查询 db.SomeCollection.aggregate([{ "$match": { "Id": "someId" } }, { "$sort": { "someISODatePropertyName": 1 } }, { "$unwind": { "path": "$somePropertyName" } }], { allowDiskUse: true }) 此查询最多返回50个项目,需要10秒才能完成 如果我只是
db.SomeCollection.aggregate([{
"$match": {
"Id": "someId"
}
}, {
"$sort": {
"someISODatePropertyName": 1
}
}, {
"$unwind": {
"path": "$somePropertyName"
}
}], {
allowDiskUse: true
})
此查询最多返回50个项目,需要10秒才能完成
如果我只是用数字更改sort属性:
db.SomeCollection.aggregate([{
"$match": {
"Id": "someId"
}
}, {
"$sort": {
"someNumericPropertyName": 1
}
}, {
"$unwind": {
"path": "$somePropertyName"
}
}], {
allowDiskUse: true
})
查询需要几毫秒才能完成
ISODate属性是否存在排序问题
我真的不明白为什么第一个版本要花这么长时间
多谢各位
更新
这是“explain”标志设置为true的查询结果(注意:在ISODate字段上有一个索引):
根据我的经验,在日期字段上没有索引的日期排序很慢。假设您经常阅读此集合,并且通常按日期排序,添加索引将是理想的解决方案 createIndex(“someISODatePropertyName”:1或-1) 试试看,这对我来说总是有很大的不同 更新: 假设这不会太慢您的写查询,请添加一个涵盖匹配和排序的索引: createIndex({“StreamId”:1,“CommitStamp”:1}) 我在我的集合上进行了测试,它将查询速度从15秒(使用日期索引)提高到不到一秒(使用新创建的索引)。仅供参考,我的最新解释显示:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.xxx",
"indexFilterSet" : false,
"parsedQuery" : {
"id" : {
"$eq" : 122
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"id" : 1,
"date" : 1
},
"indexName" : "id_1_date_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[122.0, 122.0]"
],
"date" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
}
根据我的经验,在日期字段上没有索引的日期排序很慢。假设您经常阅读此集合,并且通常按日期排序,添加索引将是理想的解决方案 createIndex(“someISODatePropertyName”:1或-1) 试试看,这对我来说总是有很大的不同 更新: 假设这不会太慢您的写查询,请添加一个涵盖匹配和排序的索引: createIndex({“StreamId”:1,“CommitStamp”:1}) 我在我的集合上进行了测试,它将查询速度从15秒(使用日期索引)提高到不到一秒(使用新创建的索引)。仅供参考,我的最新解释显示:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.xxx",
"indexFilterSet" : false,
"parsedQuery" : {
"id" : {
"$eq" : 122
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"id" : 1,
"date" : 1
},
"indexName" : "id_1_date_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[122.0, 122.0]"
],
"date" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
}
是的,我忘了提到我已经在那个字段上建立了索引(顺便说一句,不是在数字字段上…),我发现奇怪的是,在一个简单的排序操作中,数字字段和日期字段之间的性能有着巨大的差异。我正在考虑解决方案。我很惊讶这个指数还不够。您是否可以尝试将explain作为一个选项来运行查询,并查看它所说的内容?谢谢,我用explain查询结果更新了帖子。我还寻找了一些值,比如:totaldocsexandered,看看索引是否需要检查很多文档。我们为什么不尝试编写一个覆盖查询,它需要检查0个文档。删除date上的索引,然后在id上写一个索引,然后是date,看看是否可行。我今天要用这个测试一下,然后给你回复(我在加利福尼亚,现在是早上6点),我已经更新了我的答案。基本上,您的索引还需要覆盖StreamId的匹配。我希望这能奏效!但是,如果您要向该集合添加大量文档,请确保您的写入不会花费太长时间。是的,我忘了提到我已经在该字段上建立了索引(顺便说一句,不是在数字上…)我觉得很奇怪的是,在一个简单的排序操作中,数字字段和日期字段之间的性能有着巨大的差异。我正在考虑解决方案。我很惊讶这个指数还不够。您是否可以尝试将explain作为一个选项来运行查询,并查看它所说的内容?谢谢,我用explain查询结果更新了帖子。我还寻找了一些值,比如:totaldocsexandered,看看索引是否需要检查很多文档。我们为什么不尝试编写一个覆盖查询,它需要检查0个文档。删除date上的索引,然后在id上写一个索引,然后是date,看看是否可行。我今天要用这个测试一下,然后给你回复(我在加利福尼亚,现在是早上6点),我已经更新了我的答案。基本上,您的索引还需要覆盖StreamId的匹配。我希望这能奏效!但是,如果您要向该集合添加大量文档,请确保您的写入不会花费太长时间。