Nos enfrentamos a un importante problema de rendimiento después de actualizar EF Core 2.2 a EF Core 3.0. Imagine un modelo de datos simple con una propiedad de navegación de colección única y cientos de campos (la realidad se ve aún más oscura):
public class Item
{
[Key]
public int ItemID {get;set;}
public ICollection<AddInfo> AddInfos {get;set;}
... // consisting of another 100+ properties!
}
y
public class AddInfo
{
[Key]
public int AddInfoID {get;set;}
public int? ItemID {get;set;}
public string SomePayload {get;set;}
}
Durante la recuperación del elemento, consultamos de la siguiente manera:
...
var myQueryable = this._context.Items.Include(i => i.AddInfos).Where(**some filter**);
... // moar filters
var result = myQueryable.ToList();
Directo, hasta este punto.
En EF 2.2, obtener esos resultados consultables en dos consultas separadas, una para Item
y otra para el AddInfo
nivel. Estas consultas suelen obtener 10.000 items
y alrededor de 250.000 AddInfos
.
Sin embargo, en EF Core 3.0, se genera una única consulta, unir AddInfo
a la izquierda a Item
esa a primera vista parece ser la mejor opción. Item
Sin embargo, nuestro debe ser recuperado con todos los más de 100 campos, por lo que no es factible proyectar a una clase más pequeña o tipo anónimo (agregar una llamada al método .Select (...)). Por lo tanto, el conjunto de resultados tiene tanta redundancia (cada uno Item
aproximadamente 25 veces) que la consulta en sí misma tarda demasiado en ejecutarse en un tiempo aceptable.
¿EF-Core 3.0 proporciona alguna opción que nos permita volver al comportamiento de consulta del viejo y bueno EF Core 2.2 veces sin grandes cambios en nuestro modelo de datos? Ya nos estamos beneficiando de este cambio en otras partes de la aplicación, pero no en este escenario particular.
¡Muchas gracias de antemano!
Actualizar
Después de una investigación más profunda, descubrí que este problema ya se aborda con Microsoft aquí y fuera de la caja, parece que no hay forma de configurar la ejecución de la consulta dividida.
fuente
Respuestas:
Según la actualización de mi pregunta inicial, las ideas fueron tan lejos como para asegurarme de que actualmente, de hecho, no hay una configuración integrada para volver a la ejecución de consultas divididas.
Sin embargo, MS proporcionó ejemplos de código sobre cómo hacer esto con cambios mínimos de código (¡para nuestro caso de uso!) Aquí .
Simplemente estamos eliminando las llamadas .Include (...) a las propiedades de navegación de la colección (las relaciones 1: n en nuestro caso, ¡las relaciones 1: 1 no se ven afectadas!). Después de buscar los elementos, simplemente estamos haciendo otra llamada usando:
Esto recupera las entidades de propiedad de navegación de la colección y, si el seguimiento de cambios está habilitado, llena automáticamente las colecciones en los elementos individuales de la
result
variable.fuente