Estoy desarrollando una API .NET 5.0. Uso EF para conectarme a una base de datos MySQL y funciona muy bien. Aunque EF está muy optimizado, tengo una consulta que tarda más de un minuto en completarse :(
Este punto final combina datos de usuario de muchas tablas en una sola consulta. Para hacer esto, uso Linq .Include(x => x.UserId) . He notado que .Include() es muy, muy lento cuando necesitas hacerlo muchas veces así:
var user = DatabaseContext.Users .Include(user => user.Item1) .ThenInclude(x => x.Item1) .Include(user => user.Item2) .Include(user => user.Item3) .Include(user => user.Item4) .Include(user => user.Item5) .ThenInclude(x => x.Item1) .SingleOrDefaultAsync(x => x.Id == userId) );En mi caso, esto lleva a que la consulta consulte más de 200.000 filas de datos de la base de datos porque EF selecciona todo de una tabla y solo al final agrega una cláusula WHERE para filtrar los datos. Ejemplo a continuación:
SELECT t.item, t.item, t.item, u.item, u.item, ..etc FROM (SELECT a.item, a.item FROM table as a LEFT JOIN table2 as c ON a.foreignid = c.id WHERE a.id == id LIMIT 2) as t LEFT JOIN table as u ON t.id = u.id LEFT JOIN (... another select) ORDER BY t.idPodría usar la carga diferida, lo que conduce a tiempos de carga significativamente más bajos, pero tengo una potencia de CPU limitada en el servidor, por lo que sería problemático ejecutar alrededor de 12 consultas cada vez que necesito estos datos. Especialmente si muchos clientes usarán este punto final al mismo tiempo (posiblemente cientos a la vez), entonces mi preferencia es hacerlo en una consulta de base de datos.
Entonces, mi pregunta es: ¿hay alguna forma de optimizar la forma en que EF maneja la instrucción .Include() o hay otra forma de obtener el resultado esperado de una manera más eficiente?