Entity Framework Performance-Problem

Habe ich eine interessante performance-Problem mit Entity Framework. Ich bin der Verwendung von Code First.

Hier ist die Struktur meiner Entitäten:

Ein Buch kann viele Bewertungen.
Eine Überprüfung ist im Zusammenhang mit einem einzigen Buch.
Eine Prüfung kann eine oder viele Kommentare.
Ein Kommentar ist im Zusammenhang mit einer Überprüfung.

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; }
}

Ich aufgefüllt, meine Datenbank mit vielen Daten und fügte hinzu, die richtigen Indizes. Ich versuche zum abrufen eines einzelnen Buches, die 10.000 Bewertungen auf es mit dieser Abfrage:

var bookAndReviews = db.Books.Where(b => b.BookId == id)
                       .Include(b => b.Reviews)
                       .FirstOrDefault();

Diesem besonderen Buch hat 10.000 Bewertungen. Die Leistung dieser Abfrage ist rund 4 Sekunden. Läuft die genau die gleiche Abfrage (mit Hilfe von SQL-Profiler) tatsächlich zurück in keine Zeit an allen. Ich die gleiche Abfrage und ein SqlDataAdapter-und benutzerdefinierte Objekte, um die Daten abzurufen, und es geschieht in unter 500 Millisekunden.

Mit ANTS Performance Profiler sieht es aus wie ein Großteil der Zeit wird damit verbracht, ein paar andere Dinge:

Die Equals-Methode aufgerufen wird, ist 50 Millionen mal.

Weiß jemand, warum es nennen müsste, diese 50 Millionen mal und wie konnte ich erhöhen Sie die Leistung für diese?

  • Hast du eigentlich sehen, welche Abfrage wird erzeugt durch deine Aussage oder sind Sie der Annahme, dass es die optimale Abfrage?
  • Geben EF-Profiler versuchen.
  • Das problem ist nicht die Abfrage, wie ich festgestellt habe. Ich nahm mir die genaue Abfrage, EF generiert und verwendet es in einer Sql-Daten-Adapter mit regelmäßigen ADO.net laden die gleichen Objekte manuell. Läuft es in weniger als einer Sekunde.
  • Was ist der IL Aussehen?
  • Ihre navigation sollte in den Eigenschaften markiert werden virtual. Ich bin mir nicht sicher, ob das im Zusammenhang oder nicht.
  • Nur wenn Sie möchten, lazy loading, was ich nicht.
  • So... This particular book has 10,000 reviews. und Sie nicht wollen, lazy loading. Sie sehen nicht, dass da ein problem? Nicht zu vergessen, Ihren Zirkelbezug in Book und Review.
  • Nein. Ich will nicht faul laden. Ich möchte eifrig laden alle 10.000 Datensätze, so kann ich bestimmen, ob wir können dies in unserer Anwendung. Wir haben Szenarien, in denen wir müssen die Last extrem großes Objekt-Graphen. Ich sehe nicht, wie machen es träge geladen vs eifrig möchte diese verbessern.
  • Versucht EF-Profiler. Was ich sagen kann, es zeigt auch die Abfrage ausführen schnell, aber gerade gibt mir eine Warnung, dass "eine große Anzahl von Objekten zurückgegeben werden." Es tut mir nicht sagen, warum Gleich aufgerufen wird, so viele Male, und wie kann ich vermeiden, dass.
  • Sehr hilfreich für Fragen wie diese Überlegungen zur Leistung von Entity Framework 4, 5 und 6. msdn.microsoft.com/en-jm/data/hh949853.aspx#2

InformationsquelleAutor Dismissile | 2011-09-13
Schreibe einen Kommentar