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

Win*_*hen 57 performance count mongodb

我目前正在使用具有数百万条数据记录的MongoDB.我发现有一件事很烦人.

当我使用'count()'函数和少量查询数据集合时,它非常快.但是,当查询的数据收集包含数千甚至数百万的数据记录时,整个系统变得非常慢.

我确保已将所需字段编入索引.

有没有人遇到过同样的事情?你是如何改善这一点的?

And*_*ich 31

现在有另一种优化,而不是创建适当的索引.

db.users.ensureIndex({name:1});
db.users.find({name:"Andrei"}).count();
Run Code Online (Sandbox Code Playgroud)

如果您需要一些计数器,我建议尽可能预先计算它们.通过使用atomic $ inc操作而根本不使用count({}).

但mongodb的人们在mongodb上努力工作,所以,count({})根据jira bug,他们正计划在mongodb 2.1中进行改进.

  • 谢谢你。假设我有数百万条这样的记录:{_id:"hash_code_here", bookname:"The Four Steps to the Epiphany",作者:"Steven-Gary-Blank",类别:10}。我有大约 100 万本书,其类别为 10,与类别 9、8、7 等相同。我的页面具有分页功能,可过滤并向我的访问者显示类别为 10 或 9 的所有书籍,或8 或 7.... 类别应该是过滤器中的标准之一。访问者还可以添加“作者”标准或其他一些标准。我怎么能用 $inc 实现它? (2认同)
  • 请注意,自 3.0 起不推荐使用 `ensureIndex`。改用`createIndex`。 (2认同)

kam*_*ber 10

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

假设您要计算名称记录:"Andrei"

您确保名称上的索引(正如您所做)和

db.users.find({name:"andrei"}, {_id:0, name:1}).count()
Run Code Online (Sandbox Code Playgroud)

通过检查是否可以检查它是否是最快的计数方法(预计算除外)

db.users.find({name:"andrei"}, {_id:0, name:1}).explain() 
Run Code Online (Sandbox Code Playgroud)

显示index_only字段设置为true.

此技巧将确保您的查询仅从ram(索引)而不是从磁盘检索记录.


Vac*_*out 7

对我来说,解决方案是将索引更改为稀疏。这取决于具体情况,请尝试一下。

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

db.Account.find({    
     "dateChecked" : { $exists : true }    
}).count()
Run Code Online (Sandbox Code Playgroud)

收集了31.8万条记录

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


Tra*_*der 5

您现在很不走运,mongodb的数量非常糟糕,并且在不久的将来不会变得更好。参见:https : //jira.mongodb.org/browse/SERVER-1752

根据经验,除非它是一次性的东西,否则很少发生,或者数据库很小,您几乎应该永远不要使用它。

正如@Andrew Orsich所述,请尽可能使用计数器(计数器的下降是全局写锁定,但无论如何都要优于count())。