Я столкнулся с интересной проблемой производительности Entity Framework. Я использую Code First.
Вот структура моих сущностей:
У книги может быть много обзоров. Рецензия связана с одной Книгой. Рецензия может иметь один или несколько комментариев. { {1}} Комментарий связан с одним обзором.
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; }
}
Я заполнил свою базу данных большим количеством данных и добавил соответствующие индексы.Я пытаюсь найти одну книгу, на которую есть 10 000 рецензий, используя следующий запрос:
var bookAndReviews = db.Books.Where(b => b.BookId == id)
.Include(b => b.Reviews)
.FirstOrDefault();
У этой конкретной книги 10 000 рецензий. Производительность этого запроса составляет около 4 секунд. Выполнение того же самого запроса (через SQL Profiler) на самом деле возвращается в кратчайшие сроки. Я использовал тот же запрос, а также SqlDataAdapter и настраиваемые объекты для извлечения данных, и это происходит менее чем за 500 миллисекунд.
Используя ANTS Performance Profiler, похоже, что большая часть времени тратится на несколько разных вещей:
Метод Equals вызывается 50 миллионов раз.
Кто-нибудь знает, зачем нужно вызывать это 50 миллионов раз и как я могу увеличить производительность для этого?