Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoDB: Simple findFirst() query for primary key is slower than expected #23950

Closed
janpio opened this issue Apr 24, 2024 · 6 comments
Closed
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: findFirst() https://www.prisma.io/docs/orm/reference/prisma-client-reference#findfirst topic: mongodb topic: performance/queries topic: performance

Comments

@janpio
Copy link
Member

janpio commented Apr 24, 2024

Here it is very clear that the prism creates a bad query for a query that is actually simple
i hope this can fixing

// from prisma query
const message = await prisma.message.findFirst({
    where: {
        id: data.messageId
    },
})

// I changed the match object in the query from Prisma with a simple match, the results were fast
// 41ms execute from Navicate
db.messages.aggregate([
    {
        "$match": {
            "_id": ObjectId("65c0aa61d2b6db513c66be4e")
        }
    },
    {
        "$project": {
            "_id": 1,
            "deviceId": 1,
            "priority": 1,
            "status": 1,
            "payload": 1,
            "maxRetry": 1,
            "expiredSendAt": 1,
            "updatedAt": 1,
            "createdAt": 1,
            "type": 1,
            "callbackUrl": 1,
            "callbackType": 1,
            "proccessId": 1,
            "delay.min": 1,
            "delay.max": 1
        }
    }
])



// The query results from Prisma are taken from the Mongo Compass performance log
// 429ms execute from Navicate
db.messages.aggregate([
    {
        "$match": {
            "$expr": {
                "$and": [
                    {
                        "$in": [
                            "$_id",
                            [
                                {
                                    "$literal": "65c0aa61d2b6db513c66be4e"
                                }
                            ]
                        ]
                    },
                    {
                        "$ne": [
                            "$_id",
                            "$$REMOVE"
                        ]
                    }
                ]
            }
        }
    },
    {
        "$project": {
            "_id": 1,
            "deviceId": 1,
            "priority": 1,
            "status": 1,
            "payload": 1,
            "maxRetry": 1,
            "expiredSendAt": 1,
            "updatedAt": 1,
            "createdAt": 1,
            "type": 1,
            "callbackUrl": 1,
            "callbackType": 1,
            "proccessId": 1,
            "delay.min": 1,
            "delay.max": 1
        }
    }
])

Originally posted by @Davidaprilio in #16916 (comment)

@janpio janpio added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. topic: performance topic: findFirst() https://www.prisma.io/docs/orm/reference/prisma-client-reference#findfirst team/client Issue for team Client. topic: mongodb labels Apr 24, 2024
@janpio janpio changed the title Simple findFirst() query for primary key is slower than expected MongoDB: Simple findFirst() query for primary key is slower than expected Apr 24, 2024
@macrozone
Copy link

@janpio are you sure this is a findFirst call?

this looks more like this issue #22812

i am pretty confident that findFirst does work properly and does not do a $in query, since I analyize this to death for my app. I also suspected findFirst to sometimes lead to collscan #23775 but in my case it was a "hidden" findUnique that i overlooked because it was caused by a library that i used. Maybe this user has a similar problem

@janpio
Copy link
Member Author

janpio commented Apr 30, 2024

are you sure this is a findFirst call?

Yes, I am pretty sure that is what was reported:

// from prisma query
const message = await prisma.message.findFirst({
    where: {
        id: data.messageId
    },
})

If what was reported was wrong, we will figure this out when trying to reproduce and fixing. We have to go from what our users tell us. If it turns out to be incorrect, great, one less issue and this can be closed.

@Davidaprilio Can you double check what I quote above from your comment message?

@Davidaprilio
Copy link

Davidaprilio commented Apr 30, 2024

I just tried it again, and sorry it turns out it really does use $eq

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient({
    errorFormat: 'pretty',
    log: ['query', 'info', 'warn', 'error'],
})

async function run() {
    const res = await prisma.message.findFirst({
        where: {
            id: '65c75988a71554b2fcd0c48d'
        },
    })
}
run()

and in console

(base) david@dell-office:~/Projects/***$ ts-node test/query.ts 
prisma:query db.messages.aggregate([ { $match: { $expr: { $and: [ { $eq: [ "$_id", { $literal: ObjectId("65c75988a71554b2fcd0c48d"), }, ], }, { $ne: [ "$_id", "$$REMOVE", ], }, ], }, }, }, { $limit: 1, }, { $project: { _id: 1, delay.min: 1, delay.max: 1, deviceId: 1, priority: 1, status: 1, payload: 1, maxRetry: 1, expiredSendAt: 1, updatedAt: 1, createdAt: 1, type: 1, callbackUrl: 1, callbackType: 1, proccessId: 1, testing: 1, }, }, ])
(base) david@dell-office:~/Projects/***$ 

Maybe I used to take the query log wrong, but the query was really very heavy.
but I still feel findFirst is heavier than a regular query
when I changed findFirst to aggregateRaw it was much lighter in the performance log, and I also replaced findFirst with the relation Messages: true to aggregateRaw and it was also lighter in terms of the performance log
I looked at the performance log in Compass

This is from the query above
image

Simple query
image

@janpio
Copy link
Member Author

janpio commented Apr 30, 2024

Ok, does that mean that the original message was a mistake? If so, I think it would be good to close this issue to make sure that is properly tracked.

I am not sure I am following with the further performance problem you describe. Do you think it is worth creating a new issue, with more information so we can fully understand and reproduce this? We would be very happy to do that. Thanks!

@Davidaprilio
Copy link

Yes, you can close this issue

and if you want to create a new issue about performance to improve I would be happy, because actually the problem from the start was performance and I was wrong in the query $in

@janpio janpio closed this as not planned Won't fix, can't repro, duplicate, stale May 6, 2024
@janpio
Copy link
Member Author

janpio commented May 6, 2024

Sure, go ahead! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: findFirst() https://www.prisma.io/docs/orm/reference/prisma-client-reference#findfirst topic: mongodb topic: performance/queries topic: performance
Projects
None yet
Development

No branches or pull requests

3 participants