Moh*_*ian 2 mongodb mongodb-query aggregation-framework
我有一个这样的查询,我想按日期对我的结果进行排序。我在 DateTime 上有一个降序索引,在 UserId 上有一个升序索引,但是当我尝试按 DateTime 对我的结果进行排序时,它变得太慢了。
db.Users.aggregate([
{ "$match" : { "UserId" : { "$in" : [NUUID("1b029f8b-a17e-3172-9247-
9cddfaf9702b")] } } },
{ "$match" : { "DateTime" : { "$gte" : ISODate("2018-08-15T12:54:38Z"),
"$lte" : ISODate("2018-08-25T12:54:38Z") } } },
{ "$sort" : { "DateTime" : -1} }, { "$skip" : 0 }, { "$limit" : 20 }])
Run Code Online (Sandbox Code Playgroud)
当我删除排序部分时,它变得太快了。我尝试如下,它也太快了。
db.Users.aggregate([
{ "$match" : { "DateTime" : { "$gte" : ISODate("2018-08-15T12:54:38Z"),
"$lte" : ISODate("2018-08-25T12:54:38Z") } } },
{ "$match" : { "UserId" : { "$in" : [NUUID("1b029f8b-a17e-3172-9247-
9cddfaf9702b")] } } },
{ "$sort" : { "UserId" : 1} },{ "$skip" : 0 }, { "$limit" : 20 }])
Run Code Online (Sandbox Code Playgroud)
为什么只有当我想按日期时间排序时它才慢?这是我文档的结构
{
"_id" : NUUID("11111111-1111-1111-1111-629f7992f895"),
"DateTime" : ISODate("2018-08-23T15:49:51.153Z"),
"UserId" : NUUID("aaaaaaaa-aaaa-aaaa-9247-9cddfaf9702b"),
"PostId" : NUUID("bbbbbbbb-bbbb-bbbb-9529-d49ae48b2604"),
"Type" : 3
}
Run Code Online (Sandbox Code Playgroud)
第一个查询的性能问题是您在DateTime(降序)和UserId(升序)上创建了单独的索引。当排序操作与谓词完全分离时,MongoDB(从 4.0 开始)无法使用索引交集对查询结果进行排序,因此如果这些是唯一可用的候选索引,则只能选择一个。
注意:尽管$match源管道中有两个阶段,但 MongoDB 服务器会将它们合并为一个$match阶段,这与使用$and.
为什么只有当我想按日期时间排序时它才慢?
在内存中对结果进行排序被认为是一项昂贵的操作,并且存在聚合阶段内存限制 (100MB),除非您还将该allowDiskUse选项添加到聚合中,否则不能超过该限制。在 MongoDB 4.0 中,查询计划器没有关于索引基数的统计信息,因此聚合将有利于支持高效排序的索引计划(就DateTime您而言)。您的第一个查询的结果将是索引扫描,以查找所有匹配DateTime值(按排序顺序)以及与具有UserId条件的每个匹配文档进行比较。
在 sorted by 的第二个查询中UserId,UserId索引可用于匹配和排序结果。结果仍然需要过滤DateTime,但UserId标准可能更具选择性,因此要扫描的文档更少。
支持这两种查询的理想索引应该是包含两者DateTime并UserId支持所需排序顺序的复合索引。例如:db.Users.createIndex({ UserId: 1, DateTime: -1})。如果添加此复合索引,您还可以删除原始{ UserId:1}索引,因为复合索引的前缀可以有效地回答相同的查询。
了解查询性能的最直接方法是explain使用executionStats. 对于聚合管道,这种级别的解释细节需要 MongoDB 3.6+;对于较旧的服务器版本,您可以解释等效的find()查询。您的聚合查询当前不包括无法在标准find()查询中表达的任何处理阶段。
有关更多信息,请参阅MongoDB 文档中的使用索引对查询结果进行排序。博客文章Optimizing MongoDB Compound Indexes也有一些有用的背景(尽管使用了来自旧版本 MongoDB 的解释输出)。
| 归档时间: |
|
| 查看次数: |
3379 次 |
| 最近记录: |