[英]Mongo count really slow when there are millions of records
//FAST
db.datasources.find().count()
12036788
//SLOW
db.datasources.find({nid:19882}).count()
10161684
关于nid的索引
有什么办法让第二个查询更快? (需要大约8秒钟)
由于MongoDB仍然需要执行完整的b-tree遍历来查找符合条件的适当数量的文档,因此计数查询(索引或其他方式)很慢。 其原因是MongoDB b-tree结构未被“计数”,这意味着每个节点不存储有关节点/子树中元素数量的信息。
这个问题在这里报告https://jira.mongodb.org/browse/SERVER-1752并且目前没有解决方法来提高性能,除了手动维护该集合的计数器,这显然有一些缺点。
另请注意,db.col.count()版本(因此没有条件)可以占用大的快捷方式,并且实际上不执行查询,因此速度很快。 也就是说它并不总是报告与计数查询相同的值,它应该返回所有元素(例如,它不会在具有高写入吞吐量的分片环境中)。 争论是否是一个错误。 我觉得是这样的。
请注意,在2.3+中引入了一个重要的优化,它应该(并确实)提高索引字段计数的性能。 请参阅: https : //jira.mongodb.org/browse/SERVER-7745
正如@Remon所说,count()必须扫描与查询/过滤器匹配的所有文档。 它是O(n),其中n是与索引匹配的文档数,如果字段未编入索引,则为集合中的文档数。
在这种情况下,您通常希望重新审视您的要求。 你真的需要一个精确的数字10161684吗? 如果精度很重要,则应为特定查询保留单独的计数器。
但在大多数情况下,精确度并不重要。 这是两个中的一个:
在我的应用程序中,我发现第二个选项是我想要的。 因此,我也限制了count()查询,以便计数在达到限制时停止。 像这样:
db.datasources.find({nid: 19882}).limit(1000).count(true)
对于用户,如果计数为1000,则显示“找到1000个或更多结果”,否则,我显示确切的数字。
至于第一种选择......我还没有想到一个简洁的解决方案。
它必须查看每个文档的每个字段。 您可以索引nid
以使计数更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.