Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Datenbankleistung ist ein umfangreiches und komplexes Thema, das einen ganzen Stapel von Komponenten umfasst: datenbank, Netzwerk, Datenbanktreiber und Datenzugriffsebenen wie EF Core. Während Ebenen auf hoher Ebene und O/RMs wie EF Core die Anwendungsentwicklung erheblich vereinfachen und die Wartung verbessern, können sie manchmal undurchsichtig sein und leistungskritische interne Details wie die ausgeführte SQL ausblenden. In diesem Abschnitt wird versucht, einen Überblick darüber zu geben, wie Sie mit EF Core eine gute Leistung erzielen und wie häufige Fallstricke vermieden werden, die die Anwendungsleistung beeinträchtigen können.
Engpässe identifizieren und messen, messen, messen
Wie immer bei der Leistung ist es wichtig, nicht in die Optimierung zu stürzen, ohne dass Daten ein Problem zeigen; wie der große Donald Knuth einmal sagte, "Vorzeitige Optimierung ist die Wurzel des bösen". Im Abschnitt "Leistungsdiagnose " werden verschiedene Möglichkeiten erläutert, um zu verstehen, wo Ihre Anwendung Zeit in der Datenbanklogik verbringt, und wie Sie bestimmte problematische Bereiche anheften. Sobald eine langsame Abfrage identifiziert wurde, können Lösungen in Betracht gezogen werden: Fehlt Ihrer Datenbank ein Index? Sollten Sie andere Abfragemuster ausprobieren?
Messen Sie Ihren Code und mögliche Alternativen immer selbst – der Abschnitt zur Leistungsdiagnose enthält einen Beispiel-Benchmark mit BenchmarkDotNet, den Sie als Vorlage für Ihre eigenen Benchmarks verwenden können. Gehen Sie nicht davon aus, dass allgemeine öffentliche Benchmarks as-is auf Ihren spezifischen Anwendungsfall anwenden; Eine Vielzahl von Faktoren wie Datenbanklatenz, Abfragekomplexität und tatsächliche Datenmengen in Ihren Tabellen kann einen tiefgreifenden Einfluss darauf haben, welche Lösung am besten geeignet ist. So werden beispielsweise viele öffentliche Benchmarks unter idealen Netzwerkbedingungen durchgeführt, bei denen die Latenz für die Datenbank fast null ist, und mit extrem leichten Abfragen, die keine Verarbeitung (oder Datenträger-E/A) auf der Datenbankseite erfordern. Obwohl dies nützlich ist, um den Laufzeitaufwand verschiedener Datenzugriffsschichten zu vergleichen, erweisen sich die Unterschiede, die sie in der Regel aufzeigen, in einer realen Anwendung oft als vernachlässigbar, wo die Datenbank tatsächliche Arbeit leistet und die Latenz zur Datenbank ein erheblicher Leistungsfaktor ist.
Aspekte der Datenzugriffsleistung
Die Gesamtleistung des Datenzugriffs kann in die folgenden allgemeinen Kategorien unterteilt werden:
- Reine Datenbankleistung. Mit relationaler Datenbank übersetzt EF die LINQ-Abfragen der Anwendung in die SQL-Anweisungen, die von der Datenbank ausgeführt werden; Diese SQL-Anweisungen selbst können mehr oder weniger effizient ausgeführt werden. Der richtige Index an der richtigen Stelle kann eine Welt von Unterschieden in der SQL-Leistung machen, oder das Umschreiben Ihrer LINQ-Abfrage kann dazu führen, dass EF eine bessere SQL-Abfrage generiert.
- Netzwerkdatenübertragung. Wie bei jedem Netzwerksystem ist es wichtig, die Datenmenge auf dem Draht zu begrenzen. Dadurch wird sichergestellt, dass Sie nur Daten senden und laden, die Sie tatsächlich benötigen, sondern auch den sogenannten "kartesischen Explosionseffekt" beim Laden verwandter Entitäten vermeiden.
- Netzwerk-Rundreisen. Abgesehen von der hin und hergehenden Datenmenge können die Netzwerkrundreisen relevant sein, da die Zeit, die für die Ausführung einer Abfrage in der Datenbank benötigt wird, durch die Zeit, die die Pakete benötigen, um zwischen Ihrer Anwendung und Ihrer Datenbank hin und her zu reisen, geringer erscheinen kann. Der Roundtrip-Aufwand hängt stark von Ihrer Umgebung ab; je weiter ihr Datenbankserver entfernt ist, desto höher ist die Latenz und der Kostenaufwand für jeden Roundtrip. Mit der Einführung der Cloud befinden sich Anwendungen zunehmend weiter entfernt von der Datenbank, und "gesprächige" Anwendungen, die zu viele Roundtrips durchführen, erfahren eine Beeinträchtigung der Leistung. Daher ist es wichtig, genau zu verstehen, wann Ihre Anwendung mit der Datenbank kontaktiert, wie viele Roundtrips ausgeführt werden und ob diese Zahl minimiert werden kann.
- EF-Laufzeitaufwand. Schließlich fügt EF selbst einen Laufzeitaufwand zu Datenbankvorgängen hinzu: EF muss Ihre Abfragen von LINQ to SQL kompilieren (obwohl dies normalerweise nur einmal erfolgen sollte), die Änderungsnachverfolgung zusätzlichen Aufwand (aber kann deaktiviert werden) usw. In der Praxis ist der EF-Overhead für reale Anwendungen wahrscheinlich in den meisten Fällen vernachlässigbar, da die Abfrageausführungszeit in der Datenbank und die Netzwerklatenz die Gesamtzeit dominiert; aber es ist wichtig zu verstehen, was Ihre Optionen sind und wie Sie einige Fallstricke vermeiden können.
Wissen Sie, was unter der Haube passiert
EF ermöglicht Es Entwicklern, sich auf geschäftslogik zu konzentrieren, indem SQL generiert, Ergebnisse materialisiert und andere Aufgaben ausgeführt werden. Wie jede Ebene oder Abstraktion blendet sie auch die Vorgänge unter der Haube aus, z. B. die tatsächlich ausgeführten SQL-Abfragen. Die Leistung ist nicht unbedingt ein kritischer Aspekt jeder Anwendung, aber bei Anwendungen, in denen sie entscheidend ist, ist es wichtig, dass der Entwickler versteht, was EF für ihn tut: das Überprüfen von ausgehenden SQL-Abfragen, das Verfolgen von Roundtrips, um sicherzustellen, dass das N+1-Problem nicht auftritt, usw.
Cache außerhalb der Datenbank
Schließlich ist die effizienteste Möglichkeit, mit einer Datenbank zu interagieren, überhaupt nicht damit zu interagieren. Anders ausgedrückt: Wenn der Datenbankzugriff in Ihrer Anwendung als Leistungsengpässe angezeigt wird, kann es sinnvoll sein, bestimmte Ergebnisse außerhalb der Datenbank zwischenzuspeichern, um Anforderungen zu minimieren. Obwohl das Zwischenspeichern Komplexität hinzufügt, ist es ein besonders wichtiger Bestandteil jeder skalierbaren Anwendung: Während die Anwendungsebene einfach skaliert werden kann, indem zusätzliche Server hinzugefügt werden, um erhöhte Last zu bewältigen, ist die Skalierung der Datenbankebene in der Regel viel komplizierter.