Problema N+1 en Rails: Detección y Solución Eficaz
Clase 18 de 33 • Curso de Creación de APIs con Ruby on Rails
Contenido del curso
Proyecto
- 3

Creación de APIs con Rails: Proyecto Blog API paso a paso
04:37 min - 4

Configuración de Gemas para Pruebas en Proyectos Rails
06:26 min - 5

Configuración de Gemas en Proyectos Rails: Arspec, Factory Bot y Database Cleaner
07:25 min - 6

Implementación de un Health Check Endpoint en API con RSpec
12:28 min - 7

Diseño de Casos de Uso y Diagramas de Entidad para Aplicaciones
03:16 min - 8

Diagrama entidad relación: usuario y post
01:41 min - 9

Modelado de Aplicaciones con TDD en Rails
05:59 min - 10

Validaciones y Pruebas TDD en Rails: Modelos USR y Post
07:07 min - 11

Implementación de Endpoints para Listar y Mostrar Posts con TDD
15:12 min - 12

Implementar controlador Posts con TDD
10:34 min - 13

Pruebas TDD para crear y actualizar posts
10:12 min - 14

Implementación de Métodos y Manejo de Excepciones en Rails API
10:23 min - 15

Active Model serializers: control total de JSON en Rails
06:03 min - 16

Búsqueda y Filtrado de Posts por Título con TDD
05:57 min - 17

Implementación de Búsqueda de Posts con Servicios en Rails
06:06 min - 18

Problema N+1 en Rails: Detección y Solución Eficaz
Viendo ahora - 19

Identificación y solución del problema N+1 en Rails
06:20 min - 20

Flujo de Autenticación en APIs con Tokens y Proveedores
05:29 min - 21

Tests con RSpec para autenticación de tokens
12:17 min - 22

Autenticación con Tokens: Implementación en Rails API
05:53 min - 23

Autenticación de Usuarios en Controladores Rails
09:19 min - 24

Autenticación y Seguridad en CRUD de Posts en Rails
09:17 min - 25

Pruebas de Creación y Actualización con Autenticación en Rails
14:21 min - 26

Probando API Ruby on Rails con Postman
10:43 min - 27

Caching en Aplicaciones Web: Funciones y Niveles
07:15 min - 28

Aceleración de Búsquedas en Rails con Caching
08:23 min - 29

Background Jobs en Rails: Conceptos y Funcionalidades
05:45 min - 30

Procesamiento en Background y Envío de Correos con Rails
09:45 min - 31

Envío de Correos en Rails con ActionMailer y Background Jobs
11:06 min - 32
Autenticación y Autorización con JWT y Auth0 en Aplicaciones Web
03:48 min
Cierre
El N+1 query problem es un fallo de rendimiento común en Rails que dispara la latencia al cargar datos relacionados. Aquí entenderás cómo ocurre en una lista de posts con datos de usuario incluidos vía serializer, por qué se vuelve costoso y la forma conceptual de reducirlo a solo dos queries sin cambiar el resultado.
¿Qué es el N+1 query problem en Rails?
En aplicaciones Rails y otros frameworks, el problema aparece cuando haces un primer query para traer una lista (por ejemplo, posts) y luego ejecutas un query adicional por cada elemento para cargar su relación (por ejemplo, el usuario). Si el serializer incluye nombre y correo del usuario, la app termina iterando sobre cada post y consultando el usuario de forma individual.
- Primer paso: un request trae la lista de posts.
- Segundo paso: la app itera post por post y hace un query para el usuario relacionado.
- Resultado: 1 query inicial + N queries adicionales por los usuarios.
- Efecto: la latencia crece linealmente con la cantidad de posts.
¿Cuál es el escenario típico con serializers?
Cuando el serializer agrega datos del usuario (nombre y correo) a cada post, la app no solo necesita los posts, también los usuarios relacionados. Sin optimización, eso implica múltiples queries adicionales al cargar la lista.
¿Qué conceptos debes reconocer?
- N+1 queries: patrón 1 + N consultas al cargar relaciones.
- Relación post-usuario: cada post pertenece a un usuario.
- Iteración: la app recorre cada post y consulta su usuario.
- Serializer: capa que incluye campos extra como nombre y correo del usuario.
¿Por qué impacta el rendimiento?
Asignando un costo estimado por consulta, el impacto se vuelve evidente. Si cada request a base de datos cuesta 100 ms y recibes 10 posts, haces 1 query para posts y 10 queries para usuarios: en total, 1100 ms. El tiempo se dispara porque sumas una consulta por cada elemento.
- Costo por consulta: 100 ms.
- 1 query por la lista de posts: 100 ms.
- N queries por los usuarios (N = 10): 1000 ms.
- Latencia total estimada: 1100 ms.
¿Qué datos del ejemplo aclaran la magnitud?
- Tamaño de la lista: 10 posts.
- Costo de cada request: 100 ms.
- Diferencia práctica: pasar de 1100 ms a 200 ms al optimizar.
¿Qué habilidades pones en práctica?
- Identificar patrones de acceso ineficientes a la base de datos.
- Estimar latencia sumando costos por query.
- Relacionar el diseño del serializer con el número de consultas.
¿Cómo pasar de N+1 a 2 queries?
La idea central es reemplazar N queries por una consulta única para los relacionados. Primero obtienes los posts y luego haces un solo query adicional para traer todos los usuarios asociados a esos posts en bloque, recogiendo la lista de IDs de los posts y pidiendo la información de los usuarios en una sola operación.
- Paso 1: hacer un query para la lista de posts (por ejemplo, 10).
- Paso 2: recolectar los IDs de esos posts en la app.
- Paso 3: hacer un solo query para traer todos los usuarios asociados a esos IDs.
- Resultado: pasas de N+1 queries a solo 2 queries.
Con los mismos números del ejemplo, la latencia estimada cae de 1100 ms a 200 ms. La carga es la misma, pero agrupada eficientemente.
¿Te ha pasado con tus endpoints que listan posts y usuarios? Comparte tu caso y qué métricas observaste al optimizar.