Performance MongoDB';计数()';速度很慢。我们如何改进/解决它?
我目前使用的MongoDB有数百万条数据记录。我发现了一件很烦人的事 当我对少量查询数据收集使用“count()”函数时,速度非常快。但是,当查询的数据收集包含数千条甚至数百万条数据记录时,整个系统会变得非常缓慢 我确保已为必填字段编制了索引Performance MongoDB';计数()';速度很慢。我们如何改进/解决它?,performance,mongodb,count,Performance,Mongodb,Count,我目前使用的MongoDB有数百万条数据记录。我发现了一件很烦人的事 当我对少量查询数据收集使用“count()”函数时,速度非常快。但是,当查询的数据收集包含数千条甚至数百万条数据记录时,整个系统会变得非常缓慢 我确保已为必填字段编制了索引 有人遇到过同样的事情吗?如何改进这一点?现在除了创建适当的索引之外,还有另一个优化 db.users.ensureIndex({name:1}); db.users.find({name:"Andrei"}).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秒-具有非稀疏索引
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万)条记录,搜索
collection size0.80 TB
- 41615毫秒,获取约4200万(420万)条记录,搜索
collection size0.80 TB
谢谢你的回答。但是,假设我想过滤掉数据记录并计算记录数。在这种情况下,$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}})