Me encuentro con un problema de rendimiento interesante con Entity Framework. Estoy usando Code First.Entity Framework Performance Issue
Aquí es la estructura de mis entidades:
Un libro puede tener muchas críticas. Una revisión está asociada a un solo libro. Una revisión puede tener uno o muchos comentarios. Un comentario está asociado con una revisión.
public class Book
{
public int BookId { get; set; }
// ...
public ICollection<Review> Reviews { get; set; }
}
public class Review
{
public int ReviewId { get; set; }
public int BookId { get; set; }
public Book Book { get; set; }
public ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int CommentId { get; set; }
public int ReviewId { get; set; }
public Review Review { get; set; }
}
He llenado mi base de datos con una gran cantidad de datos y he añadido los índices adecuados. Estoy tratando de recuperar un solo libro que tiene 10.000 comentarios con esta consulta:
var bookAndReviews = db.Books.Where(b => b.BookId == id)
.Include(b => b.Reviews)
.FirstOrDefault();
Este libro en particular tiene 10.000 comentarios. El rendimiento de esta consulta es de alrededor de 4 segundos. Ejecutar exactamente la misma consulta (a través del Analizador de SQL) realmente regresa en muy poco tiempo. Usé la misma consulta y un SqlDataAdapter y objetos personalizados para recuperar los datos y ocurre en menos de 500 milisegundos.
Usando HORMIGAS Performance Profiler se ve como una mayor parte del tiempo se gasta haciendo algunas cosas diferentes:
El método equals se está llamando 50 millones de veces.
¿Alguien sabe por qué tendría que llamar esto 50 millones de veces y cómo podría aumentar el rendimiento de esto?
¿De verdad buscaba ver qué consulta genera su declaración o supone que es la consulta óptima? –
Prueba EF Profiler. –
El problema no es la consulta que he indicado. Tomé la consulta exacta que genera EF y la utilicé en un Adaptador de Datos Sql usando ADO.net regular, cargando los mismos objetos manualmente. Se ejecuta en menos de un segundo. – Dismissile