第一次使用mongo开发系统,最近遇到了性能问题,发现索引建的不好,该集合是用来存储采集的信息,字段包括发布日期publishDate(int型)、分值blendedScore(int型)、发布时间publishTime(date型)、相似数量similarNum(int型)、是否垃圾isRubbish(int型)以及信息自身的一些字段(不涉及查询及排序在此不再罗列),数量大概有千万级。
业务描述:
1)可按发布日期倒序+得分倒序+发布时间倒序。
2)可按相似数量倒序+发布时间倒序。
3)可按发布时间倒序。
以上三种情况都可按照发布日期、是否垃圾、关键词等进行搜索。
简化为mongo查询语句如下:
1)db.infos.find{
publishDate:{$gte:20160310,$lte:20160318},isRubbish:0}.sort{
publishDate:-1,blendedScore:-1,publishTime:-1}
2)db.infos.find{
publishDate:{$gte:20160310,$lte:20160318},isRubbish:0}.sort{
similarNum:-1,publishTime:-1}
3)db.infos.find{
publishDate:{$gte:20160310,$lte:20160318},isRubbish:0}.sort{
publishTime:-1}
为了得到最优的结果进行了以下尝试
第一次创建的索引:
db.infos.ensureIndex({
isRubbish:1,publishDate:-1,blendedScore:-1,similarNum:-1,publishTime:-1},{
name:"SortIdx",background:true});
考虑到节省空间,第一次按上面的方式试图将所有排序字段都放到一个索引中。这种方式的结果是:
1)业务1走索引速度最快。
2)业务2走索引,速度可接受。
3)业务3走索引,但速度慢到无法接受。
这种结果显然无法接受,所以继续修改索引。
第二次创建的索引:
db.infos.ensureIndex({publishDate:-1,blendedScore:-1,publishTime:-1},{name:"ScoreSortIdx",background:true}); //索引1
db.infos.ensureIndex({similarNum:-1,publishTime:-1},{name:"HotSortIdx",background:true}); //索引2
db.infos.ensureIndex({publishTime:-1},{name:"TimeSortIdx",background:true}); //索引3
由于每个业务的排序方式差别较大,而mongodb每次查询只会使用一个索引所以按照上面的方式创建了三个索引。这样创建后每个业务查询速度都很快。由于isRubbish是各个查询基本都会带的条件,所以考虑将isRubbish加入索引中,但是isRubbish字段只有0、1的取值,可能用作索引的意义不大,所以针对业务1的查询测试了一下。测试方法就是在该集合上再创建一个增加了isRubbish的字段的索引,创建语句: