代码之家  ›  专栏  ›  技术社区  ›  Martin Bories

js mongodb find:顺序比并行快,为什么?

  •  1
  • Martin Bories  · 技术社区  · 6 年前

    我遇到了一个奇怪的行为,这与我对MongoDB的了解相矛盾:

    我有4个空藏品。我做 find 在每个集合和度量上,查询需要多长时间才能完成。

    对于“parallel”测试,我使用 await Promise.all(queries) . 对于“sequential”测试,我使用“await querys[0..3]启动所有查询。

    我希望,由于集合是空的,因此测量的时间通常很低,并行请求的执行速度比顺序请求快一些。这些查询是针对localhost的,这意味着将数据从客户端传输到mongodb服务器并返回不会增加太多开销。

    然而,结果是:

    并行: 二千零八 毫秒

    相继的: ms

    也许我的代码有问题?

    当我在一个循环中多次执行查询时,会收到以下结果:

    平行1:2008.642 ms

    顺序1:2.344ms

    平行线2:1004.544ms

    顺序2:5.273ms

    平行3:2.152ms

    顺序3:3.605ms

    平行4:2.189ms

    顺序4:3.885ms

    每当我重新启动程序时,都会收到类似的结果(有或没有删除/重新创建集合)。

    我的问题: 为什么并行查询比顺序查询需要更多的时间? 为什么并行请求会随着每个请求的完成而加快,但在重新启动node.js软件时会重置请求持续时间?

    由于这种行为,我希望原因出现在node.js代码或mongodb node.js驱动程序中。

    我的代码:

    import {
        MongoClient,
        ObjectID,
    } from 'mongodb';
    
    const run = async () => {
        const client = await MongoClient.connect('mongodb://localhost:27017/mydatabase', {
                useNewUrlParser: true
            }),
            db = client.db('mydatabase'),
            userId = new ObjectID();
    
        // create collections
        await db.dropCollection('collection1');
        await db.dropCollection('collection2');
        await db.dropCollection('collection3');
        await db.dropCollection('collection4');
        await db.createCollection('collection1');
        await db.createCollection('collection2');
        await db.createCollection('collection3');
        await db.createCollection('collection4');
    
        // measure read fullfill times
        for (let i = 1; i < 5; ++i) {
            console.time(`Parallel ${i}`);
            await Promise.all([
                    db.collection('collection1')
                        .find()
                        .toArray(),
    
                    db.collection('collection2')
                        .find()
                        .toArray(),
    
                    db.collection('collection3')
                        .find()
                        .toArray(),
    
                    db.collection('collection4')
                        .find()
                        .toArray(),
            ]);
            console.timeEnd(`Parallel ${i}`);
    
            console.time(`Sequential ${i}`);
            await db.collection('collection1')
                .find()
                .toArray();
    
            await db.collection('collection2')
                .find()
                .toArray();
    
            await db.collection('collection3')
                .find()
                .toArray();
    
            await db.collection('collection4')
                .find()
                .toArray();
            console.timeEnd(`Sequential ${i}`);
        }
    };
    
    run();
    

    编译后的代码可以在这里找到: https://pastebin.com/ETmPPbzd

    最好的问候

    1 回复  |  直到 6 年前
        1
  •  2
  •   klhr    6 年前

    由于这种行为,我希望原因出现在node.js代码或mongodb node.js驱动程序中。

    是的,你说得对!它在Mongo客户端池中。第一次创建池时,它只有一个连接。当你一次问4个请求时,它会尝试打开更多的连接,并且通常会进入一个糟糕的状态。 http://mongodb.github.io/node-mongodb-native/core/driver/reference/pool/

    如果你设置了 poolSize 对于您的连接,应该可以看到并行和串行之间的类似性能。还有一个 minSize option 这将使用适当数量的连接初始化连接池,并确保池大小永远不会低于最小大小。