Перейти к содержимому

20. Оптимизация запросов

Производительность — критически важный аспект любого приложения, работающего с базой данных. Prisma предоставляет инструменты для диагностики и устранения проблем с производительностью.

N+1 — одна из самых частых проблем ORM. Она возникает, когда для получения N связанных записей выполняется N+1 отдельных запросов вместо одного:

// ❌ ПЛОХО — N+1 проблема (1 запрос + N запросов)
const posts = await prisma.post.findMany() // 1 запрос
for (const post of posts) {
const author = await prisma.user.findUnique({ // N запросов!
where: { id: post.authorId },
})
}
// ✅ ХОРОШО — один запрос с JOIN
const posts = await prisma.post.findMany({
include: { author: true }, // 1 запрос с JOIN
})

Вместо загрузки всех полей используйте select:

// ❌ Загружаем все поля включая большие blobs
const users = await prisma.user.findMany()
// ✅ Загружаем только нужные поля
const users = await prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
// avatar: false — не загружаем blob
},
})

Индексы критически важны для производительности. Всегда индексируйте поля, по которым фильтруете:

model Post {
id Int @id
authorId Int
title String
createdAt DateTime
// Индекс для запросов WHERE authorId = X ORDER BY createdAt
@@index([authorId, createdAt])
// Индекс для полнотекстового поиска
@@index([title])
}

Настройте пул соединений для вашей нагрузки:

DATABASE_URL="postgresql://user:pass@localhost/db?connection_limit=10&pool_timeout=20"
// ❌ Загружать всё — плохая идея для больших таблиц
const all = await prisma.post.findMany()
// ✅ Использовать пагинацию
const page = await prisma.post.findMany({
skip: 0,
take: 20,
})