Я сталкиваюсь с интересной проблемой производительности с Entity Framework. Я использую Code First.
Вот структура моих сущностей:
В книге может быть много обзоров. Обзор связан с одной книгой. В обзоре может быть одно или несколько комментариев. Комментарий связан с одним обзором.
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();
В этой книге есть 10000 обзоров. Производительность этого запроса составляет около 4 секунд. Выполнение одного и того же запроса (через SQL Profiler) фактически возвращается в кратчайшие сроки. Я использовал тот же запрос и SqlDataAdapter и пользовательские объекты для извлечения данных, и это происходит менее чем за 500 миллисекунд.
Используя ANTS Performance Profiler, похоже, что основная часть времени расходуется на несколько разных вещей:
Метод Equals называется 50 миллионов раз.
Кто-нибудь знает, почему ему нужно было бы назвать это 50 миллионов раз и как я мог бы увеличить производительность для этого?