问题描述
所以我在我的数据库中有一个带有以下shardkey的集合:{cl:yyyy-mm,user_id:N}
So i have a collection in my db with the following shardkey : {cl:"yyyy-mm", user_id:N}
当我执行以下查询时
db.collection.find({ cl:"2012-03", user_id:{$in:users}, _id:{"$lt":new ObjectId('4f788b54204cfa4946000044')} }).sort({_id:-1}).limit(5).explain(true)
它给我这个结果:
"clusteredType" : "ParallelSort",
"shards" : {
"set1/hostname.com:27018" : [
{
"cursor" : "BtreeCursor cl_1_user_id_1 multi",
"nscanned" : 21294,
"nscannedObjects" : 21288,
"n" : 5,
"scanAndOrder" : true,
"millis" : 1258,
"nYields" : 69,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : { ...
那我怎么能做到排序使用索引然后我不需要扫描所有21288文件,只是为了返回最后5个?
So how can I make the sort to use the index then I dont need to scan all 21288 documents, just to return last 5 ?
推荐答案
感谢shoutout在Dex!
Thanks for the shoutout on Dex!
如果在2013年这里还不算太晚,我建议在这里避免使用scanAndOrder的索引是{_id:-1,cl:1,user_id:1} 。
If it's not too late here in 2013, the index I recommend for avoiding scanAndOrder here is { _id: -1, cl: 1, user_id: 1 }.
原因是因为_id on _id和$ in on user_id构成了多个索引buckets的范围。除上述之外的任何其他顺序的索引意味着这些存储桶仍必须一起排序以满足_id上的排序。通过首先放置_id,索引中访问的所有文档都将提前正确排序。
The reason is because an $lt on _id and an $in on user_id constitute ranges across multiple index "buckets". An index of any other order than the above means those buckets must still be sorted together to satisfy a sort on _id. By putting _id first, all documents visited in the index will be properly-ordered in advance.
请注意,这比Andre的建议略有改进({_id:-1 ,user_id:1,cl:1},这也应该避免使用scanAndOrder),因为它允许对cl进行直线等效检查以修剪结果。
Note that this is a slight improvement over Andre's suggestion ({ _id: -1, user_id: 1, cl: 1 }, which should also avoid scanAndOrder) because it allows the straight equivalency check on cl to prune results.
检出了解更多细节。
这篇关于删除“scanAndOrder” :在我的MongoDB查询结果中为true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!