MongoDB排序速度极慢,即使在索引字段上也是如此。

6
今天我遇到了一个问题,我的MongoDB查询非常缓慢并超时。我发布了这个问题 - MongoDB too many records?,他的建议是正确的,我必须确保索引并删除大小写不敏感性。我在Mongo shell中尝试了一下,它完美地工作了。
然而,当我通过PHP运行它时,情况仍然是一样的:(
然后我意识到查询在"id"字段上有一个排序(不是_id),当我去掉它时,事情变得非常快。但是有了排序,它真的很慢。我已经在id字段上有一个索引。
这是查询方式:
db.tweet_data.find({ 
...     $or: 
...         [ 
...             { in_reply_to_screen_name: /^kunalnayyar$/, handle: /^kaleycuoco$/, id: { $gt: 0 } }, 
...             { in_reply_to_screen_name: /^kaleycuoco$/, handle: /^kunalnayyar$/, id: { $gt: 0 } } 
...         ], 
...     in_reply_to_status_id_str: { $ne: null } 
...     
...     } ).sort({id:-1})explain()

所以我的索引是:(非复合){{id:-1},{handle:1},{in_reply_to_screen_name:1}} 在阅读一些内容后,我意识到它应该是一个组合索引,并尝试了两个变体,但都没有成功:1. {handle:1, in_reply_to_screen_name:1, id:-1} 2. {id:-1,handle:1, in_reply_to_screen_name:1} 我不确定自己哪里做错了,但我很确定这里的问题是索引。我只是太兴奋了,无法理解索引的顺序和字段。

取决于文档中字段的顺序。尝试使用 {in_reply_to_screen_name:1, handle:1} 或 {in_reply_to_screen_name:1, handle:1, id:-1}。 - Aafreen Sheikh
只有 {in_reply_to_screen_name:1, handle:1} 不起作用,因为 {id:-1} 上有排序。我已经尝试了 handle、in_reply 和 id 的两种变化,但都没有起作用。 - Ayush Chaudhary
1
此外,请注意explain()中的nScanned数字与n之间的差异。 - Stennie
这变得越来越奇怪了。这是我的索引 "key" : { "in_reply_to_screen_name" : 1, "handle" : 1, "created_at" : -1 } 我运行了一个查询 $or: ... ... [ ... ... { in_reply_to_screen_name: /^kunalnayyar$/, handle: /^kaleycuoco$/}, ... ... { in_reply_to_screen_name: /^kaleycuoco$/, handle: /^kunalnayyar$/} ... ... ] ... ... ... ... } ).sort({created_at:-1}).explain() 它仍然没有使用索引! - Ayush Chaudhary
是的,没有 OR 语句时,它显然使用了索引。 - Ayush Chaudhary
显示剩余5条评论
1个回答

1

你应该对查询运行explain,它将帮助你弄清楚发生了什么。

很可能Mongo没有同时使用索引进行过滤和排序。当你使用$or时,它可以使用多个索引来匹配选项。但是当你添加一个sort时,它可能不会使用可用于过滤的索引。

当你想在查询中进行排序时,你需要确保排序字段在你想要命中的索引中(最后一个),否则它无法用于排序。

你也可以通过传递索引提示来加快速度。我不知道你的查询匹配了多少文档,但如果它是一个小数量的文档,并且你确保初始条件命中了一个索引,那么对_id进行排序可以快速完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接