mongo 批量查询越来越慢原因分析

 我们数据库里有4000W数据,现在想将里面的数据规整一下放到另一张表里(数据类型规整),于是写 了java个程序进行类型转换,然后一条条的查出来处理后再插入到mongo里,在此之前也有过这样的经历,但是并不是一次性存入这样大量的数据,没有瓶颈存在,后来发现当我总数100W左右,整个程序就会假死状态,不能查询也不能插入,刚开始我认为是mongo性能瓶颈了,于是去查看服务器,发现cpu,内存,连接数都很正常,一点都不高,就是不执行;监听Java堆栈也未发现异常,很奇怪,也没找到原因;再后来分析因为我是insertOne,mongo在插入数据的时候会有一次数据验证,比如ObjectId是否重复等,也许是我这种连续插入让mongo这个验证卡住了,,暂时锁住了表。。当我退出程序,,锁就自动关了(个人)

mongo查询:http://www.360doc.com/content/15/1230/15/20874412_524191840.shtml 说了下mongo查询:

mongo的查询,使用cursur查询的时候,如果没有设置batch size这个参数,那么mongo默认会返回101条数据,等这101条数据读取完了,也就是想读取第102条的时候,那么驱动会再去数据库读取下一批数据,这批数据不是用条数来限定的,而是最大限制为4m,放入内存,等该数据读完了再去取下一次4M; mongo本身为异步读写;

但我觉得并不是这样,因为我每一次查询的时候都driver都会有日志输出(mongo Java driver)自带的,每一次都会去请求数据库,我还是认为是我的链接太频繁让mongo连接池卡住了(读写)

于是我手动设置了batchSize后,发现读取的时候不会每一次都有日志输入了,说明它真的是每一次去拿50000条数据,一次链接申请;

再使用insertMany,却发现每次最大写入为1000条,这个速度已经赶上我开50个线程用最开始的单条读写了(现在为单线程);

public static void insert(Document query){
    FindIterable<Document> findIterable = mv150.collection.find(query).batchSize(50000);//batchSize 设置每次取出数据量
    MongoCursor<Document> cursor = findIterable.iterator();

    InsertManyOptions options = new InsertManyOptions();//不开启验证/ 效率更快
    options.ordered(false);
    //ExecutorService executorService = Executors.newFixedThreadPool(100); 本来最开始想用多线程
    final List<Document> list = new ArrayList<>();
    while(cursor.hasNext()){
        final Document d = cursor.next();
        list.add(resetBDLPType(d));
        if(list.size()==50000){
           /* executorService.submit(new Runnable() {
                @Override
                public void run() {
                    mvbasic.collection.insertMany(list);
                }
            });*/
            mvbasic.collection.insertMany(list,options);
            list.clear();
        }

    }
    cursor.close();
}
 


后来找到验证开关,并关闭了开关,效率是高了不少,具体效率高了多少没有测,反正count数据的时候比刚才没有关闭的时候快多了
InsertManyOptions options = new InsertManyOptions();//不开启验证/ 效率更快
options.ordered(false);
final List<Document> list = new ArrayList<>();
while(cursor.hasNext()){
    final Document d = cursor.next();
    list.add(resetBDLPType(d));
    if(list.size()==50000){
        mvbasic.collection.insertMany(list,options);
        list.clear();
    }

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值