Abfrageleistung optimieren

Verwenden Sie Query Explain, um den Abfrageausführungsplan und das Laufzeitprofil zu erhalten und so langsame Abfragen zu beheben. Im folgenden Abschnitt werden Schritte beschrieben, die Sie zur Optimierung der Abfrageleistung je nach Ausführungsprofil ausführen können:

Anzahl der Ergebnisse begrenzen

Mit dem Feld „Zurückgegebene Datensätze“ im Ausführungsbaum können Sie feststellen, ob bei der Abfrage viele Dokumente zurückgegeben werden. Sie sollten die Anzahl der zurückgegebenen Dokumente mit der $limit-Klausel begrenzen. Dadurch wird die serialisierte Byte-Größe der Ergebnisse reduziert, wenn sie über das Netzwerk an die Clients zurückgegeben werden. Wenn dem Limit-Knoten ein MajorSort-Knoten vorangestellt ist, kann die Abfrage-Engine die Limit- und MajorSort-Knoten zusammenführen und eine vollständige In-Memory-Materialisierung und ‑Sortierung durch eine TopN-Sortierung ersetzen. Dadurch wird der Speicherbedarf für die Abfrage reduziert.

Größe des Ergebnisdokuments begrenzen

Sie können die Größe des zurückgegebenen Dokuments begrenzen, indem Sie die $project-Klausel verwenden, um das Abrufen unnötiger Felder zu vermeiden. Dadurch werden die Rechen- und Speicherkosten für die Verarbeitung von Zwischenergebnissen und die serialisierte Bytegröße der Ergebnisse reduziert, wenn sie über das Netzwerk an die Clients zurückgegeben werden. Wenn alle in der Abfrage referenzierten Felder von einem regulären Index (nicht vom Typ „multikey“) abgedeckt werden, kann die Abfrage auch vollständig durch den Indexscan abgedeckt werden. So müssen keine Dokumente aus dem primären Speicher abgerufen werden.

Indexe verwenden

Folgen Sie der Anleitung unten, um Indexe einzurichten und zu optimieren.

Prüfen, ob für die Abfrage ein Index verwendet wird

Sie können feststellen, ob für die Abfrage ein Index verwendet wird, indem Sie die Blattknoten im Ausführungsbaum prüfen. Wenn der Blattknoten des Ausführungsbaums ein TableScan-Knoten ist, bedeutet das, dass für die Abfrage kein Index verwendet wird und Dokumente aus dem primären Speicher gescannt werden. Wenn ein Index verwendet wird, werden im Blattknoten des Ausführungsbaums die Index-ID und die Indexfelder des Index angezeigt.

Prüfen, ob der verwendete Index optimiert werden kann

Ein Index ist für eine Abfrage nützlich, wenn er die Anzahl der Dokumente reduzieren kann, die die Abfrage-Engine aus dem primären Speicher abrufen muss, oder wenn seine Feldreihenfolge die Sortieranforderung der Abfrage erfüllen kann.

Wenn ein Index für eine Abfrage verwendet wird, die Abfrage-Engine aber weiterhin viele Dokumente abruft und verwirft (was durch einen Scan-Knoten mit vielen zurückgegebenen Datensätzen gefolgt von einem Filter-Knoten mit wenigen zurückgegebenen Datensätzen erkennbar ist), ist das ein Zeichen dafür, dass das mit dem Index erfüllte Abfrageprädikat nicht selektiv ist. Informationen zum Erstellen eines geeigneteren Index finden Sie unter Indexe erstellen.

Wenn für eine Abfrage ein Index ohne mehrere Schlüssel verwendet wird, die Abfrage-Engine aber trotzdem eine In-Memory-Neusortierung des Ergebnissatzes durchführt (erkennbar an einem MajorSort-Knoten im Ausführungsbaum der Abfrage), ist das ein Zeichen dafür, dass der verwendete Index nicht verwendet werden kann, um die Sortieranforderung der Abfrage zu erfüllen. Informationen zum Erstellen eines geeigneteren Index finden Sie im nächsten Abschnitt.

$lookup-Abfragen optimieren

Sie können $lookup-Abfragen optimieren, indem Sie der Sammlung from Indexe hinzufügen. Dadurch kann der Vorgang passende Dokumente effizient finden, ohne die gesamte Sammlung zu scannen.

$lookup mit localField und foreignField

Wenn Sie die Optionen localField und foreignField in der Phase $lookup verwenden, erstellen Sie einen Index für foreignField in der Sammlung from.

$lookup mit verschachtelten Pipelines

Wenn Sie die Option pipeline in der Phase $lookup mit $match-Phasen verwenden, erstellen Sie einen Index für die Felder, die in der externen Sammlung enthalten sind, um einen vollständigen Scan der Sammlung zu vermeiden:

  • Erstellen Sie für $match Phasen mit Filtersemantik (z. B. {$match: {a: true}}) einen Index für die Felder in der fremden Sammlung (a).
  • Erstellen Sie für $match Phasen mit Aggregationssemantik, in denen ein Feld mit einem konstanten Wert (z. B. {$match: {$expr: {$gt: [a, 10]}}}) oder mit Gleichheitsvergleichen (eq oder in) zwischen Feldern und Variablen verglichen wird, die in let definiert sind (z. B. {$match: {$expr: {$eq: [a, "$$a"]}}}), einen Index für die Felder, die in der externen Sammlung enthalten sind. Beachten Sie, dass der Index mit mehreren Schlüsselvariablen nicht in der Planung verwendet wird.

Indexe erstellen

Folgen Sie der Dokumentation zur Indexverwaltung, um Indexe zu erstellen. Damit in Ihrer Abfrage Indexe verwendet werden können, erstellen Sie reguläre (nicht Multikey-)Indexe mit Feldern in der folgenden Reihenfolge:

  1. Alle Felder, die in Gleichheitsoperatoren verwendet werden. Um die Wahrscheinlichkeit der Wiederverwendung über Abfragen hinweg zu maximieren, sollten Sie die Felder in absteigender Reihenfolge der Häufigkeit der Felder in Gleichheitsoperatoren zwischen Abfragen anordnen.
  2. Alle Felder, nach denen sortiert werden soll (in derselben Reihenfolge).
  3. Felder, die in Bereichs- oder Ungleichheitsoperatoren verwendet werden, in absteigender Reihenfolge der Selektivität der Abfragebeschränkung.
  4. Felder, die als Teil einer Abfrage im Index zurückgegeben werden: Wenn Sie solche Felder in den Index aufnehmen, kann die Abfrage über den Index abgedeckt werden und es ist nicht erforderlich, das Dokument aus dem primären Speicher abzurufen.

Für Abfragen, bei denen Arrayfelder gefiltert und sortiert werden, sollten Sie Multikey-Indizes erstellen.

Abfragehinweis verwenden

Wenn Sie einen besser geeigneten Index für die Abfrage erstellt haben, die Abfrage-Engine diesen Index aber nicht verwendet, können Sie die Indexpräferenz der Abfrage-Engine mit einem Abfragehinweis überschreiben.

Weitere Informationen zur Ausgabe einer mit „Query Explain“ ausgeführten Abfrage finden Sie in der Referenz zur Abfrageausführung.