MongoDB'count()'非常慢。我们如何改进/解决它?

问题描述:

我目前正在使用MongoDB和数百万条数据记录。我发现了一件非常烦人的事情。MongoDB'count()'非常慢。我们如何改进/解决它?

当我使用'count()'函数进行少量查询数据收集时,速度非常快。但是,当查询的数据收集包含数千甚至数百万条数据记录时,整个系统变得非常缓慢。

我确定我已经索引了必填字段。

有人遇到过相同的东西吗?你如何改善这一点?

现在有另一个优化比创建适当的索引。

db.users.ensureIndex({name:1}); 
db.users.find({name:"Andrei"}).count(); 

如果你需要一些计数器,我建议他们可以预先计算它们。通过使用原子$inc操作并根本不使用count({})

但是mongodb家伙在mongodb上努力工作,所以,count({})根据jira bug在mongodb 2.1中计划的改进。

+0

感谢您的回答。但是,假设我想过滤掉数据记录并计算记录编号。在这种情况下,$ inc对我帮助不大,是吗? –

+0

@WinstonChen:这取决于你的过滤器。提供一个我会回答的例子。 –

+1

谢谢。假设我拥有数百万条这样的记录:{_ id:“hash_code_here”,书名:“主显节的四个步骤”,鉴定人:“Steven-Gary-Blank”,类别:10}。我有100万本左右的书籍,其类别为10,与第9,8,7等类别相同。我有一个带有分页功能的页面,该分页功能可以过滤掉所有带有类别10或9的书籍,并向我的访问者显示。 8或7 ....该类别应该是筛选器中的标准之一。访客还可以添加“作者”标准或其他标准。我怎么能用$ inc来实现它? –

您可以确保索引真正在没有任何磁盘访问的情况下使用。

比方说,你要指望用名记载:“安德烈”

你保证指标名称(如你所做的) 和

db.users.find({name:"andrei"}, {_id:0, name:1}).count() 

你可以检查,这是最快的通过检查是否

db.users.find({name:"andrei"}, {_id:0, name:1}).explain() 

显示一个index_only字段设置为true的计数方式(除了预计算)。

这个技巧将确保您的查询将只从RAM(索引)而不是从磁盘检索记录。

+0

如果MongoDB决定它不应该为'count'这样的操作执行'index_only',默认情况下,这听起来就像是一个bug。 – kizzx2

+0

这是真的在2011年,也许这已经改变https://jira.mongodb.org/browse/SERVER-1752 – kamaradclimber

现在你几乎不走运了,在mongodb计数很糟糕,在不久的将来不会变好。参见:https://jira.mongodb.org/browse/SERVER-1752

根据经验,除非是一次性事情,否则很少发生,或者数据库很小,否则几乎不会使用它。作为@Andrew Orsich所说的,尽可能使用计数器(对计数器的下降是全局写入锁定,但优于count()无论如何)。

对我来说,解决方案是改变指数为稀疏。 这取决于具体情况,只要尝试一下就可以了。

db.Account.createIndex({ "date_checked_1": 1 }, { sparse: true }) 

db.Account.find({  
    "dateChecked" : { $exists : true }  
}).count() 

318在收集数以千计的记录

  • 0.31秒 - 与稀疏索引
  • 0。79秒 - 非稀疏指数