Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.91k stars 3.83k forks source link

Performance degradation when upgrading from Mongoose v4 to v8 (findOne slower than find) #14906

Open 0Ams opened 3 weeks ago

0Ams commented 3 weeks ago

Prerequisites

Mongoose version

8.6.3

Node.js version

v18.20.4

MongoDB version

4.4.25

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

No response

Issue

Description:

I am currently in the process of upgrading Mongoose from version 4 to version 8 in our project, and I've encountered a significant performance issue.

Summary:

Details:

Steps to Reproduce:

Expected Behavior:

Actual Behavior:

IslandRhythms commented 2 weeks ago

Mongoose version 4.13.21 1.938ms

const mongoose = require('mongoose');

const testSchema = new mongoose.Schema({
    name: String,
    val: Number
});

const Test = mongoose.model('Test', testSchema);

async function main() {
    for (let i = 0; i < 100; i++) {
        const doc = new Test();
        doc.name = 'Test',
        doc.val = i;
        doc.save(function(err) {

        });
    }
}

async function run() {
    Test.findOne({}, function (err, doc) {
        console.log('doc', doc);
    });
}

(async () => {
    await mongoose.connect('mongodb://localhost:27017/performance-test');
    // await mongoose.connection.dropDatabase();
    await main();
    console.time('performanceTest')
    await run();
    console.timeEnd('performanceTest');
    console.log(mongoose.version)
    process.exit(0);
})();

Mongoose version 8.7.0 10.779ms

const mongoose = require('mongoose');

const testSchema = new mongoose.Schema({
    name: String,
    val: Number
});

const Test = mongoose.model('Test', testSchema);

async function main() {
    for (let i = 0; i < 100; i++) {
        await Test.create({
            name: 'Test',
            val: i
        })
    }
}

async function run() {
    const res = await Test.findOne();
    console.log(res);
}

(async () => {
    await mongoose.connect('mongodb://localhost:27017/performance-test');
    await mongoose.connection.dropDatabase();
    await main();
    console.time('performanceTest')
    await run();
    console.timeEnd('performanceTest');
    console.log(mongoose.version)
    process.exit(0);
})();
billouboq commented 2 weeks ago

if we lean the two do we get the same results ? To know if it's mongoose related or driver related

IslandRhythms commented 2 weeks ago

lean causes a +/- change of 1 ms.

billouboq commented 2 weeks ago

So might be driver related I guess

0Ams commented 1 week ago

As for the comparison I made, it was not about saving tests but rather a comparison of the commands like findOne, find, and lean. I am sharing part of a test results. the slowness was observed not only in the actual application connected to MongoDB, but also in a test code using a mongodb-memory-server.

Result

mongoose@8.x

šŸš€      mongoose version: 8.7.1     šŸš€
# Schema Validation time: 66.71 ms
# Insert time: 357.36 ms
# FindOne time: 2944.64 ms
# FindOneLean time: 1519.38 ms
# Find time: 722.51 ms

Only the contents of the replica connection were implemented according to the version, and there was a difference when index, shard, and schema were all used in the same state