我有一个集合test
,上面有一个带两个字段的复合索引
db.test.createIndex({ i: 1, j: 1 })
当我执行以下管道时
db.test.aggregate([{ $sort: { i: 1, j: 1 } }], { allowDiskUse: false })
它运行良好。但是这个管道
db.test.aggregate([{ $sort: { i: 1, j: -1 } }], { allowDiskUse: false })
失败,错误为";排序超出内存限制";。原因不太清楚。管道中的排序顺序与索引中的顺序不匹配,因此mongodb决定不使用索引并对整个集合进行排序,这反过来又不适合内存。
然而,我怀疑mongodb可能稍微聪明一点。与其对整个集合进行排序,它可以使用索引来分隔文档块(字段i
相同(,然后仅对这些块内的文档进行排序。同一块的文档有更多的机会放入内存,因此流水线可以更有效地执行。我可以让mongodb服务器这样做吗?怎样如果没有,是什么阻止了这种情况。
看起来mongod没有识别出可以使用索引的人,但你可以试着提示他如下:
db.test.aggregate([ {$sort:{i:1,j:-1}} ],{hint:"i_1_j_1"})
几天后,这里也提出了类似的问题。正如@Tom Slabbaert在评论中提到的那样,答案是否定的,在撰写本文时,MongoDB似乎不支持在所描述的情况下使用索引来提供增量排序。没有(非黑客的(方法可以强迫系统这样做,尤其是以一种灵活并带来性能优势的方式。
关于提高性能的假定目标,需要考虑的一些额外事项:
- 你在这里努力实现的最终结果是什么?是否有特殊原因需要复合排序和/或索引无法调整(以降序排列
j
以允许其支持排序( - 示例管道显式地将
allowDiskUse
设置为false
。这有原因吗?将其设置为true
应允许操作成功完成 - 与此相关的是,
allowDiskUse
现在默认为true
,从6.0版本开始
Edit:根据评论,MongoDB中对该功能的请求似乎在这里或这里被跟踪。