8 Stimmen

Wie kann man die Kompilierzeit von Entity Framework 4-Abfragen reduzieren?

Zusammenfassung: Wir haben Probleme mit EF4-Abfragekompilierungszeiten von 12+ Sekunden. Mit zwischengespeicherten Abfragen kommen wir nur bedingt weiter. Gibt es Möglichkeiten, die Kompilierungszeit zu reduzieren? Gibt es irgendetwas, das wir vielleicht falsch machen und nach dem wir suchen können? Vielen Dank!

Wir haben ein EF4-Modell, das über die WCF-Dienste zugänglich ist. Für jeden unserer Entitätstypen stellen wir eine Methode zum Abrufen und Zurückgeben der gesamten Entität zur Anzeige/Bearbeitung einschließlich einer Reihe von referenzierten untergeordneten Objekten bereit.

Für eine bestimmte Entität müssen wir 31 Tabellen/Untertabellen einbeziehen, um alle relevanten Daten zurückzugeben. Leider macht dies die EF-Abfragekompilierung untragbar langsam: Es dauert 12-15 Sekunden, um eine 7.800 Zeilen lange, 300K große Abfrage zu kompilieren und zu erstellen. Dies ist das Back-End einer Web-Benutzeroberfläche, die schneller sein muss als das.

Gibt es etwas, was wir tun können, um dies zu verbessern? Wir können CompiledQuery.Compile dies - das tut keine Arbeit bis zur ersten Verwendung und so hilft die zweite und nachfolgende Ausführungen, aber unser Kunde ist nervös, dass die erste Verwendung sollte nicht langsam sein entweder. Wenn der IIS-App-Pool, in dem der Webdienst gehostet wird, recycelt wird, verlieren wir den zwischengespeicherten Plan, obwohl wir die Lebenszeit erhöhen können, um dies zu minimieren. Außerdem sehe ich keine Möglichkeit, dies im Voraus zu kompilieren und/oder den von EF kompilierten Abfrage-Cache zu serialisieren (abgesehen von Reflection-Tricks). Das CompiledQuery-Objekt enthält nur eine GUID-Referenz in den Cache, also ist es der Cache, um den wir uns wirklich kümmern. (Schreiben Sie diese aus es fällt mir ein, ich kann etwas im Hintergrund von app_startup starten, um alle Abfragen auszuführen, um sie kompiliert zu bekommen - ist das sicher?)

Aber selbst wenn wir dieses Problem lösen, bauen wir unsere Suchanfragen dynamisch mit LINQ-to-Entities-Klauseln auf, je nachdem, nach welchen Parametern wir suchen: Ich glaube nicht, dass der SQL-Generator gut genug ist, um die gesamte Logik in die SQL-Schicht zu verlagern, so dass wir unsere Suchabfragen nicht vorkompilieren können. Das ist weniger schlimm, weil die Suchdatenergebnisse weniger Tabellen verwenden und die Kompilierung daher nur 3-4 Sekunden dauert und nicht 12-15, aber der Kunde ist der Meinung, dass das für die Endbenutzer immer noch nicht wirklich akzeptabel ist.

Wir müssen also die Abfragekompilierungszeit irgendwie reduzieren. Irgendwelche Ideen?

  • Das Profiling weist auf ELinqQueryState.GetExecutionPlan als Startpunkt hin, und ich habe versucht, dort hineinzugehen, aber ohne den echten .NET 4-Quellcode konnte ich nicht sehr weit kommen, und der von Reflector generierte Quellcode lässt mich nicht in einige Funktionen hineingehen oder Haltepunkte darin setzen.
  • Das Projekt wurde von .NET 3.5 aktualisiert, also habe ich versucht, das EDMX in EF4 von Grund auf neu zu generieren, für den Fall, dass etwas damit nicht stimmt, aber das hat nicht geholfen.
  • Ich habe das hier angepriesene EFProf-Dienstprogramm ausprobiert, aber es sieht nicht so aus, als würde es in diesem Fall helfen. Bei meiner großen Abfrage stürzt der Datensammler ohnehin ab.
  • Ich habe die generierte Abfrage durch die SQL-Leistungsoptimierung laufen lassen, und sie hat bereits 100 % Indexnutzung. Ich kann keinen Fehler in der Datenbank erkennen, der Probleme mit dem Abfragegenerator verursachen würde.
  • Gibt es etwas O(n^2) im Ausführungsplan-Compiler - ist das Aufteilen in Blöcke von separaten Datenladungen statt alle 32 Tabellen auf einmal wahrscheinlich hilfreich? Die Einstellung von EF auf Lazy-Load hat nicht geholfen.
  • Ich habe das EF4-Buch von O'Reilly und Julie Lerman gekauft, aber ich kann darin nichts finden, was über das "Zusammenstellen Ihrer Abfragen" hinausgeht.

Ich verstehe nicht, warum es 12-15 Sekunden dauert, einen einzigen Select über 32 Tabellen zu generieren, also bin ich optimistisch, dass es noch Verbesserungsmöglichkeiten gibt!

Danke für alle Vorschläge! Wir laufen gegen SQL Server 2008, falls das wichtig ist und XP / 7 / Server 2008 R2 mit RTM VS2010.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X