Leistungs DiagnosePerformance Diagnosis

In diesem Abschnitt wird erläutert, wie Sie Leistungsprobleme in ihrer EF-Anwendung erkennen. Nachdem ein problematischer Bereich identifiziert wurde, können Sie diese weiter analysieren, um das Problem zu identifizieren.This section discusses ways for detecting performance issues in your EF application, and once a problematic area has been identified, how to further analyze them to identify the root problem. Es ist wichtig, alle Probleme sorgfältig zu diagnostizieren und zu untersuchen, bevor Sie zu den Schlussfolgerungen springen, und um zu vermeiden, dass die Ursache des Problems ist.It's important to carefully diagnose and investigate any problems before jumping to any conclusions, and to avoid assuming where the root of the issue is.

Identifizieren langsamer Daten Bank Befehle über die ProtokollierungIdentifying slow database commands via logging

Am Ende des Tages werden von EF die Befehle vorbereitet und ausgeführt, die für die Datenbank ausgeführt werden. bei relationalen Datenbanken bedeutet das, SQL-Anweisungen über die ADO.net-Datenbank-API auszuführen.At the end of the day, EF prepares and executes commands to be executed against your database; with relational database, that means executing SQL statements via the ADO.NET database API. Wenn eine bestimmte Abfrage zu viel Zeit in Anspruch nimmt (z. b. weil ein Index fehlt), kann dies erkannt werden, indem die Befehle zur Befehlsausführung überprüft werden und Sie beobachten, wie lange Sie tatsächlich dauern.If a certain query is taking too much time (e.g. because an index is missing), this can be seen discovered by inspecting command execution logs and observing how long they actually take.

EF vereinfacht das Erfassen von Ausführungszeiten von Befehlen sehr einfach über einfache Protokollierung oder Microsoft. Extensions. Logging:EF makes it very easy to capture command execution times, via either simple logging or Microsoft.Extensions.Logging:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Blogging;Integrated Security=True")
        .LogTo(Console.WriteLine, LogLevel.Information);
}

Wenn der Protokolliergrad auf festgelegt ist LogLevel.Information , gibt EF eine Protokollmeldung für jede Befehlsausführung mit der folgenden Zeit aus:When the logging level is set at LogLevel.Information, EF emits a log message for each command execution with the time taken:

info: 06/12/2020 09:12:36.117 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [b].[Id], [b].[Name]
      FROM [Blogs] AS [b]
      WHERE [b].[Name] = N'foo'

Der obige Befehl hat 4 Millisekunden gedauert.The above command took 4 milliseconds. Wenn ein bestimmter Befehl mehr als erwartet erfordert, haben Sie einen möglichen Fehler bei einem Leistungsproblem festgestellt und können sich nun darauf konzentrieren, um zu verstehen, warum er langsam ausgeführt wird.If a certain command takes more than expected, you've found a possible culprit for a performance issue, and can now focus on it to understand why it's running slowly. Die Befehls Protokollierung kann auch Fälle anzeigen, in denen unerwartete Datenbankroundtrips durchgeführt werden. Dies würde als mehrere Befehle angezeigt werden, bei denen nur eine erwartet wird.Command logging can also reveal cases where unexpected database roundtrips are being made; this would show up as multiple commands where only one is expected.

Warnung

Es ist in der Regel eine gute Idee, die Protokollierung der Befehlsausführung in der Produktionsumgebung zu aktivieren.Leaving command execution logging enabled in your production environment is usually a bad idea. Die Protokollierung selbst verlangsamt Ihre Anwendung und kann schnell sehr große Protokolldateien erstellen, die den Datenträger des Servers auffüllen können.The logging itself slows down your application, and may quickly create huge log files which can fill up your server's disk. Es wird empfohlen, sich nur für ein kurzes Zeitintervall anzumelden, um Daten zu sammeln, während Sie Ihre Anwendung sorgfältig überwachen oder Protokollierungs Daten auf einem präproduktionssystem erfassen.It's recommended to only keep logging on for a short interval of time to gather data - while carefully monitoring your application - or to capture logging data on a pre-production system.

Korrelieren von Daten Bank Befehlen mit LINQ-AbfragenCorrelating database commands to LINQ queries

Ein Problem bei der Protokollierung der Befehlsausführung ist, dass es manchmal schwierig ist, SQL-Abfragen und LINQ-Abfragen zu korrelieren: die von EF ausgeführten SQL-Befehle können sich von den LINQ-Abfragen unterscheiden, von denen Sie generiert wurden.One problem with command execution logging is that it's sometimes difficult to correlate SQL queries and LINQ queries: the SQL commands executed by EF can look very different from the LINQ queries from which they were generated. Zur Unterstützung dieser Schwierigkeit empfiehlt es sich, das Feature " Abfrage Tags " von EF zu verwenden, mit dem Sie einen kleinen, identifizierenden Kommentar in die SQL-Abfrage einfügen können:To help with this difficulty, you may want to use EF's query tags feature, which allows you to inject a small, identifying comment into the SQL query:

var myLocation = new Point(1, 2);
var nearestPeople = (from f in context.People.TagWith("This is my spatial query!")
                     orderby f.Location.Distance(myLocation) descending
                     select f).Take(5).ToList();

Das Tag wird in den Protokollen angezeigt:The tag shows up in the logs:

-- This is my spatial query!

SELECT TOP(@__p_1) [p].[Id], [p].[Location]
FROM [People] AS [p]
ORDER BY [p].[Location].STDistance(@__myLocation_0) DESC

Häufig ist es sinnvoll, die wichtigsten Abfragen einer Anwendung auf diese Weise zu markieren, damit die Befehlsausführung die Protokolle schneller lesbar wird.It's often worth tagging the major queries of an application in this way, to make the command execution logs more immediately readable.

Weitere Schnittstellen zur Erfassung von LeistungsdatenOther interfaces for capturing performance data

Es gibt verschiedene Alternativen zum Protokollierungs Feature von EF zum Erfassen von Ausführungszeiten von Befehlen, die möglicherweise leistungsfähiger sind.There are various alternatives to EF's logging feature for capturing command execution times, which may be more powerful. Datenbanken verfügen in der Regel über eigene Ablaufverfolgungs-und Leistungsanalyse Tools, die in der Regel umfangreichere, datenbankspezifische Informationen über einfache Ausführungszeiten bereitstellen. die tatsächliche Einrichtung, die Funktionen und die Verwendung variieren in den Datenbanken erheblich.Databases typically come with their own tracing and performance analysis tools, which usually provide much richer, database-specific information beyond simple execution times; the actual setup, capabilities and usage vary considerably across databases.

SQL Server Management Studio ist beispielsweise ein leistungsfähiger Client, der eine Verbindung mit Ihrer SQL Server Instanz herstellen und wertvolle Verwaltungs-und Leistungsinformationen bereitstellen kann.For example, SQL Server Management Studio is a powerful client that can connect to your SQL Server instance and provide valuable management and performance information. Es geht über den Rahmen dieses Abschnitts hinaus, die Details zu überschreiten, aber zwei zu beachnende Funktionen sind der Aktivitäts Monitor, der ein Live-Dashboard der Serveraktivität (einschließlich der teuersten Abfragen) und das Feature für Erweiterte Ereignisse (XEvent) bereitstellt, mit dem Sie beliebige Daten Erfassungs Sitzungen definieren können, die auf ihre exakten Anforderungen zugeschnitten sind.It's beyond the scope of this section to go into the details, but two capabilities worth mentioning are the Activity Monitor, which provides a live dashboard of server activity (including the most expensive queries), and the Extended Events (XEvent) feature, which allows defining arbitrary data capture sessions which can be tailored to your exact needs. In der SQL Server Dokumentation zur Überwachung finden Sie weitere Informationen zu diesen Features und anderen.The SQL Server documentation on monitoring provides more information on these features, as well as others.

Ein weiterer Ansatz zur Erfassung von Leistungsdaten ist die Erfassung von Informationen, die entweder von EF oder dem Datenbanktreiber über die- DiagnosticSource Schnittstelle automatisch ausgegeben werden, und dann die Analyse dieser Daten oder die Anzeige auf einem Dashboard.Another approach for capturing performance data is to collect information automatically emitted by either EF or the database driver via the DiagnosticSource interface, and then analyze that data or display it on a dashboard. Wenn Sie Azure verwenden, bietet Azure-Anwendung Insights standardmäßig eine solche leistungsfähige Überwachung, die Datenbankleistung und Abfrage Ausführungszeiten in die Analyse der Art und Weise, wie schnell Ihre Webanforderungen verarbeitet werden, zu integrieren.If you are using Azure, then Azure Application Insights provides such powerful monitoring out of the box, integrating database performance and query execution times in the analysis of how quickly your web requests are being served. Weitere Informationen hierzu finden Sie im Tutorial zur Application Insights Leistungund auf der Seite Azure SQL-Analyse.More information on this is available in the Application Insights performance tutorial, and in the Azure SQL analytics page.

Überprüfen von Abfrage AusführungsplänenInspecting query execution plans

Wenn Sie auf eine problematische Abfrage geklickt haben, die optimiert werden muss, wird im nächsten Schritt in der Regel der Ausführungsplan der Abfrage analysiert.Once you've pinpointed a problematic query that requires optimization, the next step is usually analyzing the query's execution plan. Wenn Datenbanken eine SQL-Anweisung empfangen, wird in der Regel ein Plan zur Ausführung des Plans erzeugt. Dies erfordert mitunter eine komplizierte Entscheidungsfindung, je nachdem, welche Indizes definiert wurden, wie viele Daten in Tabellen vorhanden sind usw. (der Plan selbst sollte in der Regel auf dem Server zwischengespeichert werden, um eine optimale Leistung zu erzielen).When databases receive a SQL statement, they typically produce a plan of how that plan is to be executed; this sometimes requires complicated decision-making based on which indexes have been defined, how much data exists in tables, etc. (incidentally, the plan itself should usually be cached at the server for optimal performance). Relationale Datenbanken bieten Benutzern in der Regel die Möglichkeit, den Abfrageplan zusammen mit der berechneten Kosten für verschiedene Teile der Abfrage anzuzeigen. Dies ist für die Verbesserung Ihrer Abfragen von Bedeutung.Relational databases typically provide a way for users to see the query plan, along with calculated costing for different parts of the query; this is invaluable for improving your queries.

Informationen zu den ersten Schritten mit SQL Server finden Sie in der Dokumentation zu Abfrage Ausführungsplänen.To get started on SQL Server, see the documentation on query execution plans. Der typische Analyse Workflow wäre, SQL Server Management Studiozu verwenden, das SQL einer langsamen Abfrage, die über eine der oben genannten Mittel festgelegt wurde, zu einfügen und einen grafischen Ausführungsplan zu erstellen:The typical analysis workflow would be to use SQL Server Management Studio, pasting the SQL of a slow query identified via one of the means above, and producing a graphical execution plan:

Anzeigen eines SQL Server Ausführungs Plans

Obwohl Ausführungspläne zunächst kompliziert erscheinen, ist es sinnvoll, sich mit Ihnen vertraut zu machen.While execution plans may seem complicated at first, it's worth spending a bit of time getting familiar with them. Es ist besonders wichtig, die mit den einzelnen Knoten des Plans verbundenen Kosten zu notieren und zu ermitteln, wie Indizes in den verschiedenen Knoten verwendet werden (oder nicht).It's particularly important to note the costs associated with each node of the plan, and to identify how indexes are used (or not) in the various nodes.

Obwohl die oben genannten Informationen für SQL Server spezifisch sind, bieten andere Datenbanken in der Regel die gleiche Art von Tools mit ähnlicher Visualisierung.While the above information is specific to SQL Server, other databases typically provide the same kind of tools with similar visualization.

Wichtig

Datenbanken generieren manchmal unterschiedliche Abfrage Pläne, abhängig von den tatsächlichen Daten in der Datenbank.Databases sometimes generate different query plans depending on actual data in the database. Wenn eine Tabelle z. b. nur wenige Zeilen enthält, kann eine Datenbank auswählen, dass kein Index für diese Tabelle verwendet wird, sondern stattdessen ein vollständiger Tabellenscan durchgeführt werden soll.For example, if a table contains only a few rows, a database may choose not to use an index on that table, but to perform a full table scan instead. Wenn Sie Abfrage Pläne für eine Testdatenbank analysieren, stellen Sie immer sicher, dass Sie Daten enthält, die dem Produktionssystem ähneln.If analyzing query plans on a test database, always make sure it contains data that is similar to your production system.

EreignisindikatorenEvent counters

In den obigen Abschnitten wurde erläutert, wie Sie Informationen zu ihren Befehlen erhalten und wie diese Befehle in der Datenbank ausgeführt werden.The above sections focused on how to get information about your commands, and how these commands are executed in the database. Darüber hinaus macht EF eine Reihe von Ereignis Indikatoren verfügbar, die genauere Informationen zu den Vorgängen in EF und ihrer Anwendung bereitstellen.In addition to that, EF exposes a set of event counters which provide more lower-level information on what's happening inside EF itself, and how your application is using it. Diese Leistungsindikatoren können sehr nützlich sein, um bestimmte Leistungsprobleme und Leistungs Anomalien zu diagnostizieren, wie z. b. Probleme bei der Abfrage Zwischenspeicherung, die eine Konstante Neukompilierung, nicht ausgelegte dbcontext-Lecks und andere verursachenThese counters can be very useful for diagnosing specific performance issues and performance anomalies, such as query caching issues which cause constant recompilation, undisposed DbContext leaks, and others.

Weitere Informationen finden Sie auf der dedizierten Seite zu den Ereignis Indikatoren von EF .See the dedicated page on EF's event counters for more information.

Benchmarktests mit EF CoreBenchmarking with EF Core

Am Ende des Tages müssen Sie manchmal wissen, ob eine bestimmte Methode zum Schreiben oder Ausführen einer Abfrage schneller als eine andere ist.At the end of the day, you sometimes need to know whether a particular way of writing or executing a query is faster than another. Es ist wichtig, die Antwort niemals zu übernehmen oder zu überdenken, und es ist äußerst einfach, einen schnellen Benchmark zu kombinieren, um die Antwort zu erhalten.It's important to never assume or speculate the answer, and it's extremely easy to put together a quick benchmark to get the answer. Beim Schreiben von Benchmarks wird dringend empfohlen, die bekannte benchmarkdotnet -Bibliothek zu verwenden, die viele Fehler behandelt, die Benutzer beim Schreiben Ihrer eigenen Benchmarks treffen: haben Sie einige Aufwärm Iterationen durchgeführt?When writing benchmarks, it's strongly recommended to use the well-known BenchmarkDotNet library, which handles many pitfalls users encounter when trying to write their own benchmarks: have you performed some warmup iterations? Wie viele Iterationen werden tatsächlich durchgeführt und warum?How many iterations does your benchmark actually run, and why? Sehen wir uns an, wie ein Benchmark mit EF Core aussieht.Let's take a look at what a benchmark with EF Core looks like.

Tipp

Das vollständige Benchmark-Projekt für die unten stehende Quelle ist hierverfügbar.The full benchmark project for the source below is available here. Es wird empfohlen, die Datei zu kopieren und als Vorlage für Ihre eigenen Benchmarks zu verwenden.You are encouraged to copy it and use it as a template for your own benchmarks.

Als einfaches Vergleichs Szenario vergleichen wir die folgenden verschiedenen Methoden zum Berechnen der durchschnittlichen Rangfolge aller Blogs in unserer Datenbank:As a simple benchmark scenario, let's compare the following different methods of calculating the average ranking of all Blogs in our database:

  • Laden Sie alle Entitäten, addieren Sie Ihre einzelnen Rang folgen, und berechnen Sie den Durchschnitt.Load all entities, sum up their individual rankings, and calculate the average.
  • Verwenden Sie wie oben beschrieben nur eine Abfrage ohne Nachverfolgung.The same as above, only use a non-tracking query. Dies sollte schneller erfolgen, da die Identitäts Auflösung nicht durchgeführt wird und die Entitäten für die Änderungs Nachverfolgung nicht per snapshotet werden.This should be faster, since identity resolution isn't performed, and the entities aren't snapshotted for the purposes of change tracking.
  • Vermeiden Sie das Laden der gesamten blobentitätsinstanzen, indem Sie nur die Rangfolge projizieren.Avoid loading the entire Blog entity instances at all, by projecting out the ranking only. Das speichert uns daran, die anderen, nicht benötigten Spalten des Blog-Entitäts Typs zu übertragen.The saves us from transferring the other, unneeded columns of the Blog entity type.
  • Berechnen Sie den Durchschnitt in der Datenbank, indem Sie ihn in die Abfrage einteilen.Calculate the average in the database by making it part of the query. Dies sollte die schnellste Methode sein, da alles in der Datenbank berechnet wird und nur das Ergebnis zurück an den Client übertragen wird.This should be the fastest way, since everything is calculated in the database and only the result is transferred back to the client.

Mit benchmarkdotnet schreiben Sie den Code, der als einfache Methode bezeichnet werden soll (genau wie ein Komponenten Test), und benchmarkdotnet führt automatisch jede Methode für eine ausreichende Anzahl von Iterationen aus, wobei zuverlässig gemessen wird, wie lange es dauert und wie viel Arbeitsspeicher zugeordnet wird.With BenchmarkDotNet, you write the code to be benchmarked as a simple method - just like a unit test - and BenchmarkDotNet automatically runs each method for sufficient number of iterations, reliably measuring how long it takes and how much memory is allocated. Hier sehen Sie die verschiedenen Methoden (der vollständige Benchmarkcode finden Sie hier):Here are the different method (the full benchmark code can be seen here):

[Benchmark]
public double LoadEntities()
{
    var sum = 0;
    var count = 0;
    using var ctx = new BloggingContext();
    foreach (var blog in ctx.Blogs)
    {
        sum += blog.Rating;
        count++;
    }

    return (double)sum / count;
}

Die Ergebnisse sind unten aufgeführt, wie von benchmarkdotnet gedruckt:The results are below, as printed by BenchmarkDotNet:

MethodeMethod MittelwertMean FehlerError StdDevStdDev MedianMedian SeitenverhältnisRatio RatiosdRatioSD Gen 0Gen 0 Gen 1Gen 1 Gen 2Gen 2 ZugeordnetAllocated
LoadentitiesLoadEntities 2.860,4 US-2,860.4 us 54,31 US-54.31 us 93,68 US-93.68 us 2.844,5 US-2,844.5 us 4.554.55 0,330.33 210,9375210.9375 70,312570.3125 - 1309,56 KB1309.56 KB
LoadentitiesnotrackingLoadEntitiesNoTracking 1.353,0 US-1,353.0 us 21,26 US-21.26 us 18,85 US-18.85 us 1.355,6 US-1,355.6 us 2.102.10 0.140.14 87,890687.8906 3,90633.9063 - 540,09 KB540.09 KB
ProjectonlyrangfolgeProjectOnlyRanking 910,9 US-910.9 us 20,91 US-20.91 us 61,65 US-61.65 us 892,9 US-892.9 us 1,461.46 0.140.14 41,015641.0156 0,97660.9766 - 252,08 KB252.08 KB
CalculateingedatabaseCalculateInDatabase 627,1 US-627.1 us 14,58 US-14.58 us 42,54 US-42.54 us 626,4 US-626.4 us 1.001.00 0.000.00 4,88284.8828 - - 33,27 KB33.27 KB

Hinweis

Wenn die-Methoden den Kontext in der-Methode instanziieren und verwerfen, werden diese Vorgänge für den Benchmarkwert gezählt, obwohl Sie streng genommen nicht Teil des Abfrage Prozesses sind.As the methods instantiate and dispose the context within the method, these operations are counted for the benchmark, although strictly speaking they are not part of the querying process. Dies sollte nicht von Bedeutung sein, wenn zwei Alternativen miteinander verglichen werden sollen (da die Kontext Instanziierung und-Entsorgung identisch sind) und eine stärker ganzheitliche Messung für den gesamten Vorgang durchführt.This should not matter if the goal is to compare two alternatives to one another (since the context instantiation and disposal are the same), and gives a more holistic measurement for the entire operation.

Eine Einschränkung von benchmarkdotnet besteht darin, dass Sie eine einfache Leistung der einzelnen Threads der von Ihnen bereitgestellten Methoden misst und daher nicht für benchmarkübergreifende Szenarios geeignet ist.One limitation of BenchmarkDotNet is that it measures simple, single-thread performance of the methods you provide, and is therefore not well-suited for benchmarking concurrent scenarios.

Wichtig

Stellen Sie immer sicher, dass Daten in der Datenbank vorhanden sind, die Produktionsdaten beim benchmarkvorgang ähneln; andernfalls stellen die Vergleichstests möglicherweise nicht die tatsächliche Leistung in der Produktion dar.Always make sure to have data in your database that is similar to production data when benchmarking, otherwise the benchmark results may not represent actual performance in production.