MongoDB - 计数如何提高性能

3

我研究了mongodb的性能。我有一个包含5亿个文档的集合。我创建了两个索引:

db.appels.createIndex({OPERATEUR_RECEVEUR:1});
db.appels.createIndex({DUREE_APPEL:1});

对于一个字段进行计数,速度很快:

15秒:

db.appels.find ( {  "DUREE_APPEL" : { "$gt" : 42 } }).count();

2秒:

 db.appels.find({OPERATEUR_RECEVEUR:"MTN"}).count();

但计算两个带有 "and" 的字段会很慢:
7分钟:
db.appels.find ( { $and : [ {  "DUREE_APPEL" : { "$gt" : 42 } }, {OPERATEUR_RECEVEUR:"MTN"} ] } ).count();

这是没有字段索引的相同时间。

最后,带有“或”条件的两个字段无法统计:

15小时并终止查询:

db.appels.find ( { $or : [ {  "DUREE_APPEL" : { "$gt" : 42 } }, {OPERATEUR_RECEVEUR:"MTN"} ] } ).count();

由于我有100列,所以无法使用多索引。我使用1个带有Debian 8、2个SSD、80 GB RAM、12个CPU和MongoDB 2.4的节点。如何提高速度?


2
为什么不能在两个字段上创建索引?在您的情况下,DUREE_APPEL和OPERATEUR_RECEVEUR。请参阅https://docs.mongodb.com/manual/core/index-compound/。 - Saleem
感谢您的回复。我事先不知道查询语句是什么,也不知道会使用多少个字段(有时一个,有时两个,等等,有时候十个)。查询语句是根据最终用户在Web界面上的选择动态生成的。如果我有100个列,就要创建成千上万个索引。 - Coustillas Pierre-Adrien
如果你不知道哪些字段需要创建索引,我建议在每个字段上都创建一个索引。我知道这样会使用额外的资源,但它可以通过快速返回数据来提高用户体验。 - Saleem
在每个字段上创建一个索引= 100个索引。通过两个在所有字段上创建复合索引= 500(大约)索引。在所有三个字段上创建复合索引= ... ... ...。然后是4、5、6...10。这是您推荐的吗? - Coustillas Pierre-Adrien
不是的。我建议在每个字段上都放置一个,这样更容易被搜索到。再次,请自行判断。 - Saleem
1个回答

0

我发现问题不在于研究,而是“count”很慢。

在相同的字段上,响应时间与结果数量成正比:

"DUREE_APPEL" : { "$gt" : 42 } --> 198 757 639 条记录 --> 32 秒

"DUREE_APPEL" : { "$gt" : 800 } --> 11 479 097 条记录 --> 1.9 秒

"DUREE_APPEL" : { "$gt" : 5000 } --> 833 961 条记录 --> 0.14 秒

索引并不是唯一的解决方案,如何解决这个问题?

使用分片(10个节点的5000万行)可能是一个解决方案吗?:https://docs.mongodb.com/manual/sharding/

Pierre


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接