Concepto clave
Optimizar queries en Prisma es como organizar una biblioteca: si sabes exactamente qué libro necesitas y dónde está, lo encuentras rápido. Si no, pierdes tiempo buscando. En producción, cada milisegundo cuenta, especialmente cuando tu aplicación de blog tiene miles de usuarios concurrentes.
El rendimiento de queries depende de tres pilares: selección precisa de datos (solo lo necesario), relaciones eficientes (evitar joins innecesarios) y uso inteligente de índices (acelerar búsquedas). Una query mal optimizada puede generar carga innecesaria en la base de datos, ralentizando toda la aplicación.
Cómo funciona en la práctica
Imagina que en tu blog necesitas mostrar una lista de artículos con sus autores y comentarios. Una aproximación ingenua sería traer todos los datos de cada tabla, pero eso es ineficiente. En su lugar, debes estructurar la query para cargar solo los campos esenciales y manejar las relaciones de forma controlada.
Paso 1: Analiza qué datos realmente necesitas para la vista. Por ejemplo, en la página principal del blog, quizás solo necesitas el título, fecha y nombre del autor, no toda la biografía.
Paso 2: Utiliza select y include de manera estratégica. Select te permite especificar exactamente qué campos traer de la tabla principal, mientras que include maneja las relaciones, pero con cuidado de no sobrecargar.
Paso 3: Aplica filtros y ordenamientos que aprovechen índices. Por ejemplo, filtrar por fecha usando un campo indexado acelera la query.
Código en acción
Veamos un ejemplo real en una aplicación de blog. Primero, la versión ineficiente:
// Query INEFICIENTE: Trae demasiados datos innecesarios
const posts = await prisma.post.findMany({
include: {
author: true, // Trae todos los campos del autor
comments: true // Trae todos los comentarios con todos sus campos
},
where: {
published: true
}
});
// Esto genera una carga pesada, especialmente si hay muchos posts o comentariosAhora, la versión optimizada:
// Query OPTIMIZADA: Selecciona solo lo necesario
const posts = await prisma.post.findMany({
select: {
id: true,
title: true,
publishedAt: true,
author: {
select: {
name: true // Solo el nombre, no toda la info del autor
}
},
comments: {
select: {
content: true,
createdAt: true
},
take: 10 // Limita a los últimos 10 comentarios
}
},
where: {
published: true,
publishedAt: {
gte: new Date('2023-01-01') // Filtro que usa índice
}
},
orderBy: {
publishedAt: 'desc' // Ordena por fecha descendente
},
take: 20 // Paginación: solo 20 posts por página
});
// Esta query es más rápida y escalableErrores comunes
- Incluir todas las relaciones sin filtrar: Usar
include: trueen relaciones grandes (como comentarios) puede traer miles de registros innecesarios. Solución: Usaselectpara especificar campos y aplicatakeowherepara limitar. - Olvidar la paginación: Cargar todos los posts de una vez en una lista infinita. Esto satura la memoria y la red. Solución: Siempre usa
takeyskippara paginar resultados. - No aprovechar índices de base de datos: Filtrar por campos no indexados (como contenido de texto) ralentiza las queries. Solución: Asegúrate de que los campos usados en
whereyorderBytengan índices en el schema. - Seleccionar campos innecesarios: Traer
content(texto largo) cuando solo necesitas el título. Solución: Revisa cadaselecty elimina lo superfluo. - Ignorar el rendimiento en desarrollo: Asumir que si funciona en local, funcionará en producción. Solución: Usa herramientas como Prisma Metrics o logs de queries para medir el rendimiento temprano.
Checklist de dominio
- ¿Usas
selecten lugar deincludecuando solo necesitas campos específicos de relaciones? - ¿Aplicas paginación con
takeyskipen listas largas? - ¿Verificas que los campos en
whereyorderBytengan índices en tu schema Prisma? - ¿Limitas el número de registros en relaciones anidadas (ej., comentarios) con
takeo filtros? - ¿Revisas regularmente los logs de queries para identificar cuellos de botella?
- ¿Evitas traer campos pesados (como BLOBs o texto largo) si no son necesarios para la vista?
- ¿Probaste tu query con datos realistas (volumen similar a producción) antes de desplegar?
Optimiza una query para el dashboard de administración del blog
En este ejercicio, mejorarás una query existente en una aplicación de blog real. Tienes un dashboard de administración donde se muestran todos los posts, sus autores y estadísticas de comentarios. La query actual es lenta porque trae demasiados datos.
- Contexto: Usa el siguiente schema Prisma como base:
model Post { id Int @id @default(autoincrement()) title String content String published Boolean @default(false) publishedAt DateTime? authorId Int author User @relation(fields: [authorId], references: [id]) comments Comment[] } model User { id Int @id @default(autoincrement()) name String email String @unique bio String? posts Post[] } model Comment { id Int @id @default(autoincrement()) content String postId Int post Post @relation(fields: [postId], references: [id]) } - Query inicial: Esta es la query actual que necesita optimización:
const allPosts = await prisma.post.findMany({ include: { author: true, comments: true } }); - Requisitos del dashboard: En el dashboard, solo necesitas mostrar: título del post, fecha de publicación, nombre del autor, y cantidad de comentarios (no los comentarios completos).
- Tarea: Refactoriza la query para que sea eficiente, aplicando las técnicas aprendidas. Escribe el código optimizado en un archivo JavaScript.
- Entrega: Proporciona el código final y una breve explicación de los cambios realizados.
- Considera usar select en lugar de include para controlar los campos exactos.
- Para contar comentarios, puedes usar una agregación en lugar de traer todos los registros.
- Asegúrate de que la query solo traiga posts publicados si es necesario para el dashboard.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.