我正在使用MongoDB 2.4.10,我有一个包含四百万条记录的集合,以及一个创建不超过50000个子集的查询,即使对于我们的超级用户也是如此。我需要从该子集中随机选择30个项目,并且考虑到跳过和限制的潜在性能问题(特别是当使用1-50000的随机跳过量进行30次时),我偶然发现了以下解决方案:
我的索引如下:
{a: 1, b: 1, c: 1, d: 1}
我还有一个单独的索引:
{d : 1}
'd'是随机区域。
我的查询如下:
db.content.find({a : {$in : ["xyz", "abc"]}, b : "ok", c : "Image"})
.sort({d : 1}).skip(X).limit(30)
当集合很小时,这很有效。但是,在我们的性能和实时系统上,此查询失败,因为它不使用a,b,c,d索引,而是仅使用此索引:
{d : 1}
因此,查询最终扫描的记录超过了所需的记录(按25倍)。所以,我介绍了提示:
db.content.find({a : {$in : ["xyz", "abc"]}, b : "ok", c : "Image"})
.hint({a : 1, b : 1, c : 1, d : 1}).sort({d : 1}).skip(X).limit(30)
现在,对于X的所有值,最高可达11000,并且explain()显示正在使用的正确索引。但是,当跳过量超过11000时,我得到:
{
"$err" : "too much data for sort() with no index. add an index or specify a smaller limit",
"code" : 10128
}
据推测,遇到此错误的风险是查询(没有提示)之前未使用此索引的原因。所以: