-
Notifications
You must be signed in to change notification settings - Fork 2k
Closed
Labels
bug/1-unconfirmedBug should have enough information for reproduction, but confirmation has not happened yet.Bug should have enough information for reproduction, but confirmation has not happened yet.kind/bugA reported bug.A reported bug.topic: intopic: mongodbtopic: performancetopic: performance/queries
Milestone
Description
Bug description
Overview
We noticed while developing a new feature using Prisma & MongoDB Connector, that simple ID $in queries were taking 450ms+ to query a single ID.
The _id field is of course indexed in MongoDB, so you'd expect the query Prisma generates to be one which will take advantage of indexing, however...
The docs for $expr state:
Indexes are not used for comparisons where the operand is an array or the operand type is undefined.
So here, our $expr takes an array to match $in, and results in a COLLSCAN through our entire collection:
"planSummary": [
{
"COLLSCAN": {}
}
],
"keysExamined": 0,
"docsExamined": 44855,
"cursorExhausted": 1,
"numYields": 350If we rewrite our $match query to be much simpler and not use $expr, it will successfully make use of the indices:
{
"_id": { "$in": [ ObjectId("5ffe656eed39c24704277f66") ] }
}Questions / Observations
- We're not managing the Mongo DB in prisma, it's already setup and configured, with the necessary indices. This all works fine in mongoose.
- I'm assuming it's not necessary to explicitly declare that an
@idprisma property is also an@@index. - Is there anything we can do to force prisma to not use
$expr? Why is the generated query using$expr?
How to reproduce
- Generate the
prismaclient using the supplied example andmongodbconnector. - Run the provided
typescriptquery. - Observe the generated
mongoquery results in aCOLLSCAN.
Expected behavior
prisma.user.findMany(
{ where: {
id: {
in: ['id1','id2'],
},
})Should take advantage of _id indices so that query performance is fast.
Prisma information
Prisma Collection
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
deactivate Boolean @default(false)
bounce Boolean @default(false)
notification Json?
bannedAt DateTime?
lineId String?
pushToken PushToken[]
Lead Lead[]
@@index([lineId])
@@map("users") // mongodb collection name.
}Calling Code
async searchUsers(
searchUsersBodyDTO: SearchUsersBodyDTO
): Promise<GetUserDTO[]> {
// Setup conditions
const conditions: Prisma.UserFindManyArgs = {}
if (searchUsersBodyDTO.ids?.length > 0) {
conditions.where = {
id: {
in: searchUsersBodyDTO.ids,
},
}
}
// Execute
return (await this.prisma.user.findMany(
conditions
)) as unknown[] as GetUserDTO[]
}Prisma Generated Aggregate Pipeline Stage
{
"$expr": {
"$and": [
{
"$in": [
"$_id",
{
"$literal": [
{
"$oid": "5ffe656eed39c24704277f66"
}
]
}
]
}
]
}
}Environment & setup
prismaversion: 4.4.0mongoversion: 4.2.23
Prisma Version
4.4.0
Reesy, eugene-yaroslavtsev, WillMeetsMore, MMoreJames, ryusaka and 7 more
Metadata
Metadata
Assignees
Labels
bug/1-unconfirmedBug should have enough information for reproduction, but confirmation has not happened yet.Bug should have enough information for reproduction, but confirmation has not happened yet.kind/bugA reported bug.A reported bug.topic: intopic: mongodbtopic: performancetopic: performance/queries