M365Con 2027 – conferencia online gratuita · 11–22 Jan 2027 · 120 sessions→ m365con.net

Blog · Mirko Peters

Acabar de una vez por todas con el problema de las consultas N+1

By ·

¡Bienvenido de nuevo, colega desarrollador! Si alguna vez has creado una aplicación con Entity Framework Core, es probable que hayas tropezado con obstáculos de rendimiento que te dejaron rascándote la cabeza. ¿Por qué una consulta que se ejecuta al instante en desarrollo se arrastra en producción? Muchas veces, el culpable está oculto a plena vista: el tristemente célebre problema de las consulta

Automatically translated with AI from the original post. Read the English original

▶ BLOGConquering the N+1 QueryProblem Once and For AllM365.FM
Titelbild: Conquering the N+1 Query Problem Once and For All

¡Bienvenido de nuevo, colega desarrollador! Si alguna vez has creado una aplicación con Entity Framework Core, es probable que hayas tropezado con obstáculos de rendimiento que te dejaron rascándote la cabeza. ¿Por qué una consulta que se ejecuta al instante en desarrollo se arrastra en producción? Muchas veces, el culpable está oculto a plena vista: el tristemente célebre problema de las consultas N+1. En esta entrada vamos a analizar a fondo qué causa este asesino silencioso del rendimiento, cómo detectarlo antes de que lo noten tus usuarios y cómo solucionarlo de forma eficaz con la carga ansiosa (eager loading), las proyecciones y técnicas de optimización inteligentes.

Antes de entrar en los detalles técnicos, no dejes de consultar el episodio de podcast relacionado: Improve Entity Framework Core Query Performance. En ese episodio repasamos varias trampas habituales de Entity Framework y compartimos consejos prácticos para que tus aplicaciones sigan funcionando a toda velocidad.

Comprender el problema de las consultas N+1

¿Qué es N+1?

El problema N+1 aparece cuando cargas datos relacionados de una forma que provoca muchas consultas adicionales. En Entity Framework Core, esto suele darse al acceder a datos relacionados dentro de un bucle. Por ejemplo, puedes obtener 100 pedidos. Luego, para cada pedido, accedes a la propiedad del cliente. Esto dispara una consulta para todos los pedidos y otras 100 consultas, una por cada cliente. Terminas con 101 consultas en lugar de una sola. Esto ralentiza tu aplicación, sobre todo cuando hay muchos datos. Con conjuntos de datos pequeños puede pasar desapercibido, pero se convierte en un gran problema en producción.

Detectar consultas N+1 en producción

Puedes identificar el problema N+1 observando cuántas consultas envía tu aplicación a la base de datos. Estas son algunas formas de detectarlo:

  • Activa el registro de SQL para ver todas las consultas que se ejecutan.
  • Usa herramientas de perfilado para comprobar el rendimiento de las consultas.
  • Supervisa el número de consultas. Si ves muchas consultas para un resultado pequeño, es posible que tengas un problema N+1.
  • Prueba tu aplicación con grandes conjuntos de datos, similares a los que usas en producción.

Consejo: revisa siempre tus registros y herramientas de perfilado después de añadir nuevas consultas o de cambiar la forma en que cargas los datos relacionados.

Solucionar N+1 con carga ansiosa (eager loading)

Puedes solucionar el problema N+1 en Entity Framework Core usando carga ansiosa (eager loading). La carga ansiosa te permite obtener todos los datos que necesitas en una sola consulta. Para ello usas el método Include. Esto indica a EF que una las tablas relacionadas y obtenga todo de una vez. Por ejemplo, si quieres obtener autores y sus libros, puedes escribir:

var authorsWithBooks = context.Authors.Include(a => a.Books).ToList();

Este código ejecuta una única consulta que une autores y libros. Tu aplicación obtiene todos los datos de una vez. La carga ansiosa reduce el número de consultas y hace tu aplicación más rápida. Deberías usarla cuando sepas que necesitas los datos relacionados desde el principio. Así evitas las ralentizaciones y mantienes tu aplicación funcionando sin problemas.

Seguimiento frente a sin seguimiento para mejorar el rendimiento

Entity Framework Core hace un seguimiento de cada entidad que carga. Es la configuración predeterminada. El seguimiento permite a EF saber si cambias algo. Pero el seguimiento puede ralentizar tu aplicación. Es más lento con conjuntos de datos grandes. Puede que notes que tu aplicación consume más memoria. Las consultas también pueden tardar más cuando el seguimiento está activado. Usar AsNoTracking hace las consultas más rápidas. Además, consume menos memoria. Tu aplicación puede responder más rápido y atender a más usuarios a la vez.

Consejo: si desactivas el seguimiento, tus consultas se ejecutan más rápido. Es lo más adecuado cuando solo necesitas leer datos.

Usa asnotracking si no quieres actualizar ni eliminar los datos: Usa asnotracking si no quieres actualizar ni eliminar los datos. La mayoría de las APIs web solo leen datos. Alrededor del 70-80 % de los endpoints solo muestran información. Estos funcionan mejor con asnotracking. Estos son algunos buenos momentos para usarlo:

  • Informes y paneles que solo muestran datos
  • Respuestas de API que devuelven listas o detalles para mostrar
  • Endpoints de búsqueda o filtrado que solo leen de la base de datos

Paginación y grandes conjuntos de datos

Cuando usas EF con grandes cantidades de datos, puedes tener problemas serios. Cargar demasiados datos de una vez puede hacer que tu aplicación vaya lenta o incluso que se bloquee. Estas son algunas de las cosas que pueden pasar:

  • Tu aplicación podría consumir demasiada memoria y quedarse sin ella.
  • Puede tardar mucho en obtener respuestas porque hay demasiados datos.
  • La base de datos podría dejar de funcionar si intentas cargar demasiado de una vez.

Puedes resolver estos problemas usando paginación. La paginación divide tus datos en partes más pequeñas. Esto hace que tu aplicación sea más rápida y fácil de usar. En EF, puedes usar Skip() y Take() para hacerlo. Skip te permite saltar algunos registros. Take obtiene solo la cantidad que necesitas. Esto te ayuda a trabajar con grandes volúmenes de datos y mantiene tu aplicación funcionando bien.

Operaciones masivas y por lotes

Puedes hacer que tu base de datos funcione más rápido con operaciones masivas. Estos métodos te permiten cambiar muchos registros al mismo tiempo. Los métodos estándar de EF sirven para trabajos pequeños. Pero se vuelven lentos cuando hay grandes cantidades de datos. Las operaciones masivas te ayudan a insertar, actualizar o eliminar miles de filas rápidamente. Puedes usarlas al importar datos desde archivos CSV. También son útiles al sincronizar registros o hacer actualizaciones nocturnas.

El procesamiento por lotes te permite agrupar acciones para que tu aplicación funcione más rápido. Puedes usar actualizaciones por lotes con UpdateRange() para cambiar muchas cosas a la vez. Intenta no llamar a SaveChanges() con demasiada frecuencia. Cada llamada envía datos a la base de datos. EF Core 7 incluye nuevos métodos como ExecuteUpdate y ExecuteDelete para cambios masivos.

Conclusión

Optimizar Entity Framework Core no tiene por qué ser una cuestión de adivinanzas. Si entiendes cómo se produce el problema de consultas N+1, usas herramientas para supervisar la generación de SQL, aprovechas la carga diligente y las consultas sin seguimiento, e incorporas la paginación y las operaciones masivas, puedes transformar una capa de datos lenta en un motor de alto rendimiento. Mide siempre tu línea base de rendimiento y prueba tus consultas a fondo en condiciones realistas.

Para profundizar aún más en estas estrategias, no dejes de escuchar el episodio complementario Improve Entity Framework Core Query Performance. ¡Aplicar estas buenas prácticas evitará cuellos de botella ocultos en tus aplicaciones y garantizará una experiencia fluida para tus usuarios!

Entities in this article

Entity Framework Core

RSS