Running a statement results in different prepared statements
See original GitHub issueBug description
I am experiencing reaching the max_prepared_stmt_count
limit in MySQL. I have found the reason to be that prisma is creating a lot of prepared statements.
We were getting information from the database and updating one field but were writing all data in the update statement. This is obviously not good and fixed on our side.
const sms = await this.prismaService.sms.findFirst({
where: { externalId },
});
sms.status = 'delivered';
await this.prismaService.sms.update({
data: sms,
where: { externalId },
});
UPDATE `xxx`.`Sms` SET `body` = ?, `x` = ?, `campaignName` = ?, `p` = ?, `externalId` = ?, `sentAt` = ?, `id` = ?, `deliveredAt` = ?, `from` = ?, `bouncedAt` = ?, `updatedAt` = ?, `to` = ?, `isRestricted` = ?, `isDeleted` = ?, `y` = ?, `status` = ?, `deletedAt` = ?, `createdAt` = ? WHERE `xxx`.`Sms`.`id` IN (?)
or
UPDATE `xxx`.`Sms` SET `body` = ?, `x` = ?, `externalId` = ?, `deletedAt` = ?, `to` = ?, `y` = ?, `createdAt` = ?, `p` = ?, `bouncedAt` = ?, `deliveredAt` = ?, `from` = ?, `id` = ?, `updatedAt` = ?, `campaignName` = ?, `sentAt` = ?, `isRestricted` = ?, `status` = ?, `isDeleted` = ? WHERE `xxx`.`Sms`.`id` IN (?)
Interestingly the keys of the fetched object are not in the same order when getting them. This model has 17 fields resulting in 355.687.428.096.000 (17!)
possible ways the prepared statement could be created.
How to reproduce
await this.prisma.sms.create({
data: {
from: 'yes',
to: 'no',
body: 'bla',
},
})
await this.prisma.sms.create({
data: {
body: 'bla',
from: 'yes',
to: 'no',
},
})
in MySQL look in performance_schema -> prepared_statements_instances and you will see two different prepared statements.
Expected behavior
I would expect that prisma normalizes this so that there is only one prepared statement. Reducing the number of prepared statements needed and thus not causing max_prepared_stmt_count
errors.
Prisma information
model Sms {
id String @id @default(uuid()) @db.Char(36)
x String? @db.Char(36)
from String
to String
y String? @db.Char(36)
externalId String?
status SmsStatus @default(initialized)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sentAt DateTime?
deliveredAt DateTime?
bouncedAt DateTime?
body String @db.Text
campaignName? String
p String? @db.Char(36)
isRestricted Boolean @default(false)
isDeleted Boolean @default(false)
deletedAt DateTime?
}
enum SmsStatus {
initialized
accepted
scheduled
queued
sending
sent
delivered
undelivered
failed
}
Environment & setup
- OS: Mac OS
- Database: MySQL
- Node.js version: v14.16.0
Prisma Version
prisma : 2.28.0
@prisma/client : 2.28.0
Current platform : darwin
Query Engine : query-engine 89facabd0366f63911d089156a7a70125bfbcd27 (at node_modules/prisma/node_modules/@prisma/engines/query-engine-darwin)
Migration Engine : migration-engine-cli 89facabd0366f63911d089156a7a70125bfbcd27 (at node_modules/prisma/node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core 89facabd0366f63911d089156a7a70125bfbcd27 (at node_modules/prisma/node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary : prisma-fmt 89facabd0366f63911d089156a7a70125bfbcd27 (at node_modules/prisma/node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash : 89facabd0366f63911d089156a7a70125bfbcd27
Studio : 0.417.0
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (7 by maintainers)
Top GitHub Comments
Reproduction:
Directly communicating with the engine using GraphQL, create one item first:
Then run a few updates with the id you got back, e.g.
I did two queries, resulting in two SQL statements that have the ordering wrong:
and
@janpio do you need any more info? We are running many thousand queries / minute at finanzcheck/smava and this is problematic for us. I’d be happy to help provide more data if needed.