mongodb系列(一)mongoose find普通查询与aggregate聚合查询的 简单性能对比

背景

mongodb 3.4,使用默认的配置(没有调整内存限制或其他性能配置),数据库有90万+条数据

 

开始实验

以下分别使用 find 查询 和 aggregate 聚合查询

以下为dao层(server/dao/cmsResourceDao.js),基于mongoose查询mongodb

getModel(){
        return mongoose.model(this.model_name); //model_name 为collection名称
}

  /***
     * 使用find 查询,并且是分页查询
     * @param limit_param 条件
     * @param page_index 数据页码起始下标
     * @param page_size 数据每页数量
     * @param sort 排序条件
     * @returns {Promise.<{rows: *, total_count: *}>}
     */
    async listPage(limit_param,page_index,page_size,sort){
        let rows;
        if(sort != null){
            rows = await this.getModel().where(limit_param).skip(Number(page_index)).limit(Number(page_size)).sort(sort).exec();
        }else{
            rows = await this.getModel().where(limit_param).skip(Number(page_index)).limit(Number(page_size)).exec();
        }
        return {rows};
    }

    /***
     * 使用aggregate聚合 查询,并且是分页查询
     * @param limit_param 条件
     * @param page_index 数据页码起始下标
     * @param page_size 数据每页数量
     * @param sort 排序条件
     * @returns {Promise.<{rows: *, total_count: *}>}
     */
    async listAggregatePage(limit_param,page_index,page_size,sort){

        let aggregate_limit = [{$match:limit_param},
            {$skip:Number(page_index)},
            {$limit:Number(page_size)}];

        if(sort != null)aggregate_limit.push({$sort:sort});

        let rows = await this.getModel().aggregate(aggregate_limit);
        return {rows};
    }

1.find查询和aggregate查询(不使用sort排序)

以下为使用find查询50000条数据返回:

 async list(ctx,next){

        console.log('list!!!');
        let type = ctx.request.query.type;
        let page_index = ctx.request.query.page_index;
        let page_size = ctx.request.query.page_size;

        let where = {};
        if(type != null)where.type = type;

        let start_time = new Date().getTime();
        let result = await dao.listPage(where,page_index,page_size);
        // let result = await dao.listAggregatePage(where,page_index,page_size); //使用聚合查询方式
        let end_time = new Date().getTime();
        console.log('查询时间:');
        console.log(end_time - start_time);
        ctx.body = {
            data : result,
            time : new Date().getTime() - start_time
        }
    }

打印的时间是: 8504ms

 使用aggregate查询50000条数据返回:

async list(ctx,next){

        console.log('list!!!');
        let type = ctx.request.query.type;
        let page_index = ctx.request.query.page_index;
        let page_size = ctx.request.query.page_size;

        let where = {};
        if(type != null)where.type = type;

        let start_time = new Date().getTime();
        // let result = await dao.listPage(where,page_index,page_size);
        let result = await dao.listAggregatePage(where,page_index,page_size); //使用聚合查询方式
        let end_time = new Date().getTime();
        console.log('查询时间:');
        console.log(end_time - start_time);
        ctx.body = {
            data : result,
            time : new Date().getTime() - start_time
        }
    }

打印的时间是: 2241ms

 

2.find查询和aggregate查询(使用sort排序)

使用sort排序挑战性能极限

在刚才使用find查询,添加sort条件

let result = await dao.listPage(where,page_index,page_size,{updated_at:-1});

结果控制台报出,内存超出限制(最大值为 33554432 bytes 折合为 32mb左右 ):

service error { MongoError: Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.

 

使用aggregate查询,添加sort条件

let result = await dao.listAggregatePage(where,page_index,page_size,{updated_at:-1}); //使用聚合查询方式

打印的时间是: 2298ms

那么aggregate查询的内存最大值究竟有多少呢?再玩大的,这次查询10万条

service error { MongoError: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt in.

由此可见 aggregate对排序也是有内存限制的(最大值为104857600 bytes折合为100mb左右)

 

总结

从查询的速度看,aggregate效率更胜一筹。

从内存限制看,aggregate比find更高一点。

 

从上述实验中,aggregate 好像比 find 查询 更胜一筹,但并不意味着 aggregate就是最好的,初步判断这是由于aggregate更消耗内存换取查询的速度。下一集,再深层次挖掘两者区别

 

PS: 源码已提交到github 

https://github.com/rcjjian/big_data_lab

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值