Performance MongoDB';计数()';速度很慢。我们如何改进/解决它?

Performance MongoDB';计数()';速度很慢。我们如何改进/解决它?,performance,mongodb,count,Performance,Mongodb,Count,我目前使用的MongoDB有数百万条数据记录。我发现了一件很烦人的事 当我对少量查询数据收集使用“count()”函数时,速度非常快。但是,当查询的数据收集包含数千条甚至数百万条数据记录时,整个系统会变得非常缓慢 我确保已为必填字段编制了索引 有人遇到过同样的事情吗?如何改进这一点?现在除了创建适当的索引之外,还有另一个优化 db.users.ensureIndex({name:1}); db.users.find({name:"Andrei"}).count(); 如果你需要一些计数器,我建

我目前使用的MongoDB有数百万条数据记录。我发现了一件很烦人的事

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

我确保已为必填字段编制了索引


有人遇到过同样的事情吗?如何改进这一点?

现在除了创建适当的索引之外,还有另一个优化

db.users.ensureIndex({name:1});
db.users.find({name:"Andrei"}).count();
如果你需要一些计数器,我建议尽可能预先计算。通过使用原子操作,而根本不使用
count({})


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

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

假设您要计算名为“Andrei”的记录

确保对名称进行索引(正如您所做的那样) 及

您可以通过检查

db.users.find({name:"andrei"}, {_id:0, name:1}).explain() 
显示设置为true的仅索引字段


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

您现在运气不好,mongodb中的计数很糟糕,在不久的将来不会变得更好。见:

根据经验,除非它是一次性的,很少发生的事情,或者您的数据库非常小,否则您几乎不应该使用它


正如@Andrew Orsich所说,尽可能使用计数器(计数器的缺点是全局写锁,但无论如何都比count()好)。

对我来说,解决方案是将索引更改为稀疏。 这取决于具体情况,如果可以的话就试试看

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

db.Account.find({    
     "dateChecked" : { $exists : true }    
}).count()
收藏中的318万张唱片

  • 0.31秒-具有稀疏索引
  • 0.79秒-具有非稀疏索引

根据最新版本的mongodb 4.4添加我的观察结果。我有
0.80 TB
收集容量

我已经为我的收藏创建了索引(
UserObject.CountryID
)。然后运行这个查询

db.users.aggregate([
{
    $match : {
        "UserObject.CountryID" : 3
    }
}]).group({_id: "Count", count: {$sum: 1}})
总共花了

  • 06800毫秒,获取约1300万(130万)条记录,搜索
    0.80 TB
    集合大小
  • 16274毫秒,获取大约3500万(350万)条记录,搜索
    0.80 TB
    collection size
  • 41615毫秒,获取约4200万(420万)条记录,搜索
    0.80 TB
    collection size


谢谢你的回答。但是,假设我想过滤掉数据记录并计算记录数。在这种情况下,$inc对我帮助不大,是吗?@WinstonChen:这取决于你的过滤器。提供一个我将回答的例子。谢谢。假设我有数百万条这样的记录:{u id:“hash_code_here”,书名:“顿悟的四个步骤”,作者:“Steven Gary Blank”,类别:10}。我有100万本左右的书,它们的类别是10,与类别9、8、7等相同。我有一个带有分页功能的页面,可以过滤并向访问者显示所有类别为10、9、8或7的书。。。。类别应该是筛选器中的条件之一。访问者还可以添加“作者”标准或其他一些标准。如何使用$inc实现它?请注意,
ensureIndex
从3.0开始就被弃用了。改为使用
createIndex
。如果MongoDB决定不应该对
count
这样的操作执行
index\u
,那么默认情况下,对我来说这听起来很像一个bug。这在2011年是真的,也许随着时间的推移,情况已经发生了变化
db.users.aggregate([
{
    $match : {
        "UserObject.CountryID" : 3
    }
}]).group({_id: "Count", count: {$sum: 1}})