欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MongoDB查询性能验证及优化 博客分类: java;nosql; mongodb全文检索 

程序员文章站 2024-03-15 09:46:59
...
结论:
1、 200w数据,合理使用索引的情况下,单个stationId下4w数据。mongodb查询和排序的性能理想,无正则时client可以在600ms+完成查询,qps300+。有正则时client可以在1300ms+完成查询,qps140+。
2、 Mongodb的count性能比较差,非并发情况下client可以在330ms完成查询,在并发情况下则需要1-3s。可以考虑估算总数的方法,http://blog.sina.com.cn/s/blog_56545fd30101442b.html

测试环境:mongodb使用 replica set,1主2从,96G内存,版本2.6.5
Mem消耗(4个200w数据的collection):
MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 

空间消耗(测试数据最终选定的collection):
MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 

Jvm: -Xms2G -Xmx2G
Ping延迟33ms
查询都使用ReadPreference.secondaryPreferred()

无正则

1、 创建stationId, firmId复合引查询场景(200w集合,12个字段)
查询次数:20000
查询条件:多条件查询10条记录,并逐条获取记录
String key = "清泉" + r.nextInt(1000);
Pattern pattern = Pattern.compile(key);
BasicDBObject queryObject = new BasicDBObject("stationId",
new BasicDBObject("$in", new Integer[]{20}))
       .append("firmId", new BasicDBObject("$gt", 5000))
      .append("dealCount", new BasicDBObject("$gt", r.nextInt(1000000)));   DBCursor cursor = collection.find(queryObject).limit(10).skip(2);
并发:200
耗时:61566
单次耗时(server):124ms
Qps:324.85

2、 创建stationId, firmId复合引查询场景(200w集合,12个字段)
查询次数:20000
查询条件:多条件查询10条记录排序,并逐条获取记录
String key = "清泉" + r.nextInt(100);
Pattern pattern = Pattern.compile(key);
BasicDBObject queryObject = new BasicDBObject("stationId",
new BasicDBObject("$in", new Integer[]{4, 20}))
        .append("firmId", new BasicDBObject("$gt", 5000))
       .append("dealCount", new BasicDBObject("$gt", r.nextInt(1000000)));   DBCursor cursor = collection.find(queryObject)
.sort(new BasicDBObject("firmId", 1)).limit(10).skip(2);
并发:200
耗时:63187
单次耗时(server):119ms
Qps:316.52

3、 创建stationId, firmId复合引查询场景(200w集合,12个字段)
查询次数:2000
查询条件:多条件查询记录数
String key = "清泉" + r.nextInt(100);
Pattern pattern = Pattern.compile(key);
BasicDBObject queryObject = new BasicDBObject("stationId",
new BasicDBObject("$in", new Integer[]{4, 20}))
    .append("firmId", new BasicDBObject("$gt", 5000))
.append("dealCount", new BasicDBObject("$gt", r.nextInt(1000000)));  
long count = collection.count(queryObject);
并发:200
耗时:21887
单次耗时(client):280ms
Qps:91.38

有正则

4、 创建stationId, firmId复合引查询场景(200w集合,12个字段)
查询次数:20000
查询条件:多条件查询10条记录,并逐条获取记录
String key = "清泉" + r.nextInt(1000);
Pattern pattern = Pattern.compile(key);
BasicDBObject queryObject = new BasicDBObject("stationId",
new BasicDBObject("$in", new Integer[]{20}))
       .append("firmId", new BasicDBObject("$gt", 5000))
       .append ("dealCount", new BasicDBObject("$gt", r.nextInt(1000000)))
       .append("firmName", pattern);
   DBCursor cursor = collection.find(queryObject).limit(10).skip(2);
并发:200
耗时:137673
单次耗时(server):225ms
Qps:145.27

5、 创建stationId, firmId复合引查询场景(200w集合,12个字段)
查询次数:20000
查询条件:多条件查询10条记录排序,并逐条获取记录
String key = "清泉" + r.nextInt(1000);
Pattern pattern = Pattern.compile(key);
BasicDBObject queryObject = new BasicDBObject("stationId",
new BasicDBObject("$in", new Integer[]{4, 20}))
      .append("firmId", new BasicDBObject("$gt", 5000))
       .append ("dealCount", new BasicDBObject("$gt", r.nextInt(1000000)))
       .append("firmName", pattern);
   DBCursor cursor = collection.find(queryObject)
.sort(new BasicDBObject("firmId", 1)).limit(10).skip(2);
并发:200
耗时:138673
单次耗时(server):230ms
Qps:144.22

6、 创建stationId, firmId复合引查询场景(200w集合,12个字段)
查询次数:2000
查询条件:多条件查询记录数
String key = "清泉" + r.nextInt(1000);
Pattern pattern = Pattern.compile(key);
BasicDBObject queryObject = new BasicDBObject("stationId",
new BasicDBObject("$in", new Integer[]{4, 20}))
        .append("firmId", new BasicDBObject("$gt", 5000))
        .append ("dealCount", new BasicDBObject("$gt", r.nextInt(1000000)))
      .append("firmName", pattern);
   long count = collection.count(queryObject);
并发:200
耗时:23155
单次耗时(client):330ms
Qps:86.37



MongoDB索引特点
1、 复合索引必须命中首字段,否则无法生效。后面的字段可以不按顺序命中。
2、 复合索引字段越多占用空间越大,但对查询性能影响不大(数组索引除外)。
3、 会根据sort字段选择索引,优先级超过复合索引中的非首字段。
 
MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 

MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 



4、 命中复合索引的情况下,数据量<10w的情况下,过滤非索引字段,效率也比较高。

MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 

5、 全文检索性能比较差,200w数据命中50w的情况下,全文检索需要10+s,正则需要1s。
6、不走索引的字段,如果用于查询,创建schema尽量靠前,可以提升查询效率。
7、索引覆盖查询,如果检索条件,排序字段和查询字段都是索引中的字段,会省去从文档中Load数据的过程,查询会更快。

MongoDB客户端配置,可以提出来做成spring注入,设置最大连接数什么的。
MongoClientOptions options =
MongoClientOptions.builder().maxWaitTime(1000 * 60 * 2)
.connectionsPerHost(500).build();
mongoClient = new MongoClient(Arrays.asList(new ServerAddress("10.205.68.57", 8700),
new ServerAddress("10.205.68.15", 8700),
new ServerAddress("10.205.69.13", 8700)), options);
mongoClient.setReadPreference(ReadPreference.secondaryPreferred());


参考文档
《深入学习MongoDB》
http://blog.163.com/wm_at163/blog/static/132173490201110254257510/
http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-java-driver/#getting-started-with-java-driver
http://mongoing.com/tj/microshard-ycsb //压力测试
http://www.cnblogs.com/xusir/archive/2012/12/24/2830957.html //命令
http://www.361way.com/mongo-mem/1489.html //内存监控
http://www.oschina.net/translate/mongodb-text-search-tutorial?cmp 全文检索
http://www.oschina.net/translate/mongodb-indexing-tip-3-too-many-fields-to-index-use //复合索引
http://blog.sina.com.cn/s/blog_56545fd30101442b.html 分页

mongoDB调研_结论.docx为最终场景下的测试数据,分为有正则和无正则。
mongoDB调研_remote.docx为测试验证过程中的数据,有可能存在缓存等情况,不一定准确,功参考。
  • MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 
  • 大小: 14.6 KB
  • MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 
  • 大小: 34.2 KB
  • MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 
  • 大小: 49.1 KB
  • MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 
  • 大小: 55.9 KB
  • MongoDB查询性能验证及优化
            
    
    博客分类: java;nosql; mongodb全文检索 
  • 大小: 44.8 KB