MongoDB 聚合查询 运行 很慢
MongoDB Aggregation query running very slow
我们在 Mongodb 中对大部分集合进行了版本化。选择的版本控制机制如下:
{ "docId" : 174, "v" : 1, "attr1": 165 } /*version 1 */
{ "docId" : 174, "v" : 2, "attr1": 165, "attr2": "A-1" }
{ "docId" : 174, "v" : 3, "attr1": 184, "attr2" : "A-1" }
因此,当我们执行查询时,我们总是需要以这种方式使用聚合框架来确保获取我们对象的最新版本:
db.docs.aggregate( [
{"$sort":{"docId":-1,"v":-1}},
{"$group":{"_id":"$docId","doc":{"$first":"$$ROOT"}}}
{"$match":{<query>}}
] );
这种方法的问题是,一旦完成分组,内存中就会有一组与您的集合无关的数据,因此您的索引无法使用。
因此,您的集合中的文档越多,查询速度就越慢。
有什么方法可以加快速度吗?
如果没有,我会考虑转向这个好的post中定义的方法之一:http://www.askasya.com/post/trackversions/
为了完成这个问题,我们选择了选项 3:一个集合保留最新版本,一个集合保留历史版本。这里介绍一下:http://www.askasya.com/post/trackversions/ and some further description (with some nice code snippets) can be found in http://www.askasya.com/post/revisitversions/.
它已经 运行 投入生产 6 个月了。到目前为止,一切都很好。以前的方法意味着我们总是使用聚合框架,一旦您修改原始模式(使用 $group、$project...),它就会远离索引,因为它不再匹配原始集合。随着数据的增长,这使我们的性能变得糟糕。
使用新方法虽然问题消失了。我们 90% 的查询都针对最新数据,这意味着我们以一个简单的 ObjectId
作为标识符的集合为目标,我们不再需要聚合框架,只需要常规查找。
我们对历史数据的查询总是包括 id
和 version
,因此通过索引它们(我们将两者都包含为 _id
,所以我们开箱即用),读取那些收集同样快。这是不容忽视的一点。在设计 collections/schemas 在 MongoDB 中的外观时,应用程序中的读取模式至关重要,因此您必须确保在做出此类决定时了解这些模式。
我们在 Mongodb 中对大部分集合进行了版本化。选择的版本控制机制如下:
{ "docId" : 174, "v" : 1, "attr1": 165 } /*version 1 */
{ "docId" : 174, "v" : 2, "attr1": 165, "attr2": "A-1" }
{ "docId" : 174, "v" : 3, "attr1": 184, "attr2" : "A-1" }
因此,当我们执行查询时,我们总是需要以这种方式使用聚合框架来确保获取我们对象的最新版本:
db.docs.aggregate( [
{"$sort":{"docId":-1,"v":-1}},
{"$group":{"_id":"$docId","doc":{"$first":"$$ROOT"}}}
{"$match":{<query>}}
] );
这种方法的问题是,一旦完成分组,内存中就会有一组与您的集合无关的数据,因此您的索引无法使用。
因此,您的集合中的文档越多,查询速度就越慢。
有什么方法可以加快速度吗?
如果没有,我会考虑转向这个好的post中定义的方法之一:http://www.askasya.com/post/trackversions/
为了完成这个问题,我们选择了选项 3:一个集合保留最新版本,一个集合保留历史版本。这里介绍一下:http://www.askasya.com/post/trackversions/ and some further description (with some nice code snippets) can be found in http://www.askasya.com/post/revisitversions/.
它已经 运行 投入生产 6 个月了。到目前为止,一切都很好。以前的方法意味着我们总是使用聚合框架,一旦您修改原始模式(使用 $group、$project...),它就会远离索引,因为它不再匹配原始集合。随着数据的增长,这使我们的性能变得糟糕。
使用新方法虽然问题消失了。我们 90% 的查询都针对最新数据,这意味着我们以一个简单的 ObjectId
作为标识符的集合为目标,我们不再需要聚合框架,只需要常规查找。
我们对历史数据的查询总是包括 id
和 version
,因此通过索引它们(我们将两者都包含为 _id
,所以我们开箱即用),读取那些收集同样快。这是不容忽视的一点。在设计 collections/schemas 在 MongoDB 中的外观时,应用程序中的读取模式至关重要,因此您必须确保在做出此类决定时了解这些模式。