Verwenden Sie „Abfrage erläutern“, um den Abfrageausführungs plan und das Laufzeit-Ausführungsprofil abzurufen und so Fehler bei langsamen Abfragen zu beheben. Im folgenden Abschnitt werden Schritte beschrieben, die Sie je nach Ausführungsprofil zur Optimierung der Abfrageleistung ausführen können:
Anzahl der Ergebnisse begrenzen
Verwenden Sie das Feld „Zurückgegebene Datensätze“ im Ausführungsbaum, um zu ermitteln, ob die Abfrage viele Dokumente zurückgibt. Sie können die Anzahl der zurückgegebenen Dokumente mit der Klausel $limit begrenzen. Dadurch wird die serialisierte Bytegröße der Ergebnisse reduziert, wenn sie über das Netzwerk an die Clients zurückgegeben werden. Wenn dem Knoten Limit ein Knoten MajorSort vorangestellt ist, kann die Abfrage-Engine die Knoten Limit und MajorSort 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 mit der
$project Klausel begrenzen, um das Abrufen
unnötiger Felder zu vermeiden. Dadurch werden die Kosten für Rechenleistung und Arbeitsspeicher für die Verarbeitung von Zwischenergebnissen sowie 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 durch einen regulären Index (nicht Multikey) abgedeckt sind, 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, um Indexe einzurichten und zu optimieren.
Ermitteln, ob die Abfrage einen Index verwendet
Sie können ermitteln, ob die Abfrage einen Index verwendet, indem Sie die Blattknoten im Ausführungsbaum prüfen. Wenn der Blattknoten des Ausführungsbaums ein TableScan-Knotenist, verwendet die Abfrage keinen Index und scannt Dokumente aus dem primären Speicher. Wenn ein Index verwendet wird, werden im Blattknoten des Ausführungsbaums die Index-ID und die Indexfelder des Index angezeigt.
Ermitteln, 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 die Feldreihenfolge die Sortieranforderung der Abfrage erfüllen kann.
Wenn ein Index für eine Abfrage verwendet wird, die Abfrage-Engine aber dennoch viele Dokumente abruft und verwirft (erkennbar an einem Scan-Knoten, der viele Datensätze zurückgibt, gefolgt von einem Filter-Knoten , der nur wenige Datensätze zurückgibt), ist das Prädikat der Abfrage, das mit dem Index erfüllt wird, nicht selektiv. Informationen zum Erstellen eines geeigneteren Index finden Sie unter Indexe erstellen.
Wenn ein Nicht-Multikey-Index für eine Abfrage verwendet wird, die Abfrage-Engine aber dennoch eine In-Memory-Neusortierung des Ergebnissatzes durchführt (erkennbar an einem MajorSort-Knoten im Abfrageausführungsbaum), kann der verwendete Index die Sortieranforderung der Abfrage nicht 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 from-Sammlung Indexe hinzufügen. So können passende Dokumente effizient gefunden werden, ohne die gesamte Sammlung zu scannen.
$lookup mit localField und foreignField
Wenn Sie die Optionen localField und foreignField in der $lookup-Phase verwenden, erstellen Sie einen Index für foreignField in der from-Sammlung.
$lookup mit verschachtelten Pipelines
Wenn Sie die Option pipeline in der $lookup-Phase mit $match-Phasen verwenden, erstellen Sie einen Index für die Felder in der externen Sammlung, um einen vollständigen Tabellenscan zu vermeiden:
- Erstellen Sie für
$match-Phasen mit Filtersemantik (z. B.{$match: {a: true}}) einen Index für die Felder in der externen Sammlung (a). - Erstellen Sie für
$match-Phasen mit Aggregationssemantik, bei denen ein Feld mit einem konstanten Wert verglichen wird (z. B.{$match: {$expr: {$gt: [a, 10]}}}) oder bei Gleichheitsvergleichen (eqoderin) zwischen Feldern und Variablen, die inletdefiniert sind (z. B.{$match: {$expr: {$eq: [a, "$$a"]}}}), einen Index für die Felder in der externen Sammlung. Multikey-Indexe werden bei der Planung nicht verwendet.
Indexe erstellen
Folgen Sie der Dokumentation zur Indexverwaltung, um Indexe zu erstellen. Damit Ihre Abfrage Indexe verwenden kann, erstellen Sie reguläre Indexe (nicht Multikey) mit Feldern in der folgenden Reihenfolge:
- Alle Felder, die in Gleichheitsoperatoren verwendet werden. Um die Wahrscheinlichkeit der Wiederverwendung über mehrere Abfragen hinweg zu maximieren, sortieren Sie die Felder in absteigender Reihenfolge ihrer Häufigkeit in Gleichheitsoperatoren in den Abfragen.
- Alle Felder, nach denen sortiert wird (in derselben Reihenfolge).
- Felder, die in Bereichs- oder Ungleichheitsoperatoren verwendet werden, in absteigender Reihenfolge der Selektivität der Abfrageeinschränkung.
- Felder, die als Teil einer Abfrage im Index zurückgegeben werden: Wenn Sie solche Felder in den Index aufnehmen, kann die Abfrage durch den Index abgedeckt werden und es ist nicht erforderlich, Dokumente aus dem primären Speicher abzurufen.
Für Abfragen, bei denen Arrayfelder gefiltert und sortiert werden, sollten Sie Multikey-Indexe erstellen.
Abfragehinweis verwenden
Wenn Sie einen geeigneteren 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 Abfrage, die mit „Abfrage erläutern“ ausgeführt wurde, finden Sie unter Referenz zur Abfrageausführung.