Verwenden Sie Query Explain, um den Abfrageausführungsplan und das Laufzeitausführungsprofil zu erhalten und so Probleme mit langsamen 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
Verwenden Sie das Feld „Zurückgegebene Datensätze“ im Ausführungsbaum, um festzustellen, ob die Abfrage viele Dokumente zurückgibt. Sie können die Anzahl der zurückgegebenen Dokumente mit der Phase limit(...) 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 mit select(...) nur die erforderlichen Felder zurückgeben oder mit remove_fields(...) zu große Felder verwerfen. 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 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.
Besseren Index ermitteln
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 weiterhin viele Dokumente abruft und verwirft (was durch einen Scan-Knoten mit vielen zurückgegebenen Datensätzen gefolgt von einem Filterknoten 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 ein Index für eine Abfrage verwendet wird, die Abfrage-Engine aber weiterhin 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.
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:
- Alle Felder, die in Gleichheitsoperatoren verwendet werden. Um die Wahrscheinlichkeit der Wiederverwendung über Abfragen hinweg zu maximieren, sortieren Sie die Felder in absteigender Reihenfolge des Vorkommens der Felder in Gleichheitsoperatoren zwischen 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 Abfragebeschrä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, das Dokument aus dem primären Speicher abzurufen.
Index- oder Tabellenscan erzwingen
Wenn Sie Cloud Firestore abfragen, werden automatisch alle Indexe verwendet, die die Effizienz der Abfrage wahrscheinlich erhöhen. Daher müssen Sie für Ihre Abfragen keinen Index angeben. Bei Abfragen, die für Ihre Arbeitslast entscheidend sind, empfehlen wir jedoch, die Option forceIndex zu verwenden, um eine konsistentere Leistung zu erzielen.
In einigen Fällen wählt Cloud Firestore jedoch einen Index aus, der die Abfragelatenz erhöht. Wenn Sie die Schritte zur Fehlerbehebung bei Leistungsabfällen ausgeführt haben und bestätigt haben, dass es sinnvoll ist, die Abfrage mit einem anderen Index zu versuchen, können Sie den Index mit der Option forceIndex angeben.
Mit der Option forceIndex können Sie in Pipelinevorgängen in jeder Eingabephase den Standardabfrageplan von Cloud Firestore überschreiben und einen zu verwendenden Index angeben oder einen Tabellenscan erzwingen.
Bestimmten Index erzwingen
Wenn Sie erzwingen möchten, dass für die Abfrage ein bestimmter Index verwendet wird, geben Sie die Index-ID als String für die Option forceIndex an. Sie finden die Index-ID in der Konsole oder in Fehlermeldungen.
Im folgenden Beispiel wird der Planner gezwungen, den Index mit der ID CICAgOi36pgK zu verwenden:
Node.js
// Force Planner to use Index ID CICAgOi36pgK await db.pipeline() .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" }) .limit(100) .execute();
Java
// Force Planner to use Index ID CICAgOi36pgK Pipeline.Snapshot results1 = firestore.pipeline() .collectionGroup("customers", new CollectionGroupOptions() .withHints(new CollectionHints().withForceIndex("CICAgOi36pgK"))) .limit(100) .execute().get();
Go
// Force Planner to use Index ID CICAgOi36pgK snapshot1 := client.Pipeline(). CollectionGroup("customers", firestore.WithForceIndex("CICAgOi36pgK")). Limit(100). Execute(ctx)
Hier sind einige Anwendungsfälle für das Erzwingen eines bestimmten Index:
- Leistung verschiedener Indexe testen
- Sicherstellen, dass für eine Abfrage ein bestimmter, bekanntermaßen optimaler Index verwendet wird.
- Überschreiben des Optimierers, wenn seine Standardauswahl für eine bestimmte Abfrage suboptimal ist.
Wenn der angegebene Index nicht gefunden wird, schlägt die Abfrage fehl.
Tabellenscan erzwingen
Bei einem Tabellenscan werden Dokumente in der Sammlung oder Sammlungsgruppe gelesen, ohne dass sekundäre Indexe verwendet werden. Wenn Sie einen Tabellenscan erzwingen möchten, legen Sie forceIndex auf primary fest.
Im folgenden Beispiel wird ein Tabellenscan erzwungen:
// Force Planner to only do a Full-Table Scan
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "primary" })
.limit(100)
In den folgenden Fällen kann ein Tabellenscan verwendet werden:
- Für sehr kleine Sammlungen, bei denen der Index-Aufwand nicht gerechtfertigt ist.
- Für Abfragen, die auf die meisten Dokumente in einer Sammlung zugreifen.
- Für das Debugging und Leistungsvergleiche.
forceIndex mit „Query Explain“ verwenden
Sie können Query Explain, insbesondere mit der Option analyze, verwenden, um die Auswirkungen von forceIndex zu beobachten:
- Prüfen Sie, ob Cloud Firestore den angegebenen Index in
forceIndexverwendet hat. Suchen Sie dazu in den Blattknoten des Ausführungsbaums nach der Index-ID. - Prüfen Sie, ob im Plan ein
TableScan-Knoten angezeigt wird, wenn SieforceIndex: "primary"verwenden. - Vergleichen Sie die Leistungsmesswerte wie Latenz, gescannte Dokumente und gescannte Indexeinträge mit und ohne
forceIndex, um die Abfrageleistung zu optimieren.
Best Practices für forceIndex
forceIndex bietet zwar mehr Kontrolle über die Ausführung von Abfragen, das Abfrageoptimierungstool von Cloud Firestore ist jedoch in der Regel für die meisten Anwendungsfälle effizient.
Beachten Sie die folgenden Best Practices bei der Verwendung von forceIndex:
- Verwenden Sie
forceIndexmit Bedacht. Wenn Sie mit dem Standardabfrageplan eine suboptimale Leistung feststellen, verwenden Sie Query Explain, um das Problem zu diagnostizieren, bevor Sie einen Index erzwingen. - Wenn Sie
forceIndexverwenden, sollten Sie Ihre Abfragen mit realistischen Datenmengen testen, um die Leistungs- und Kostenmerkmale zu ermitteln. - Vermeiden Sie die Verwendung von
forceIndex: "primary"für große Sammlungen in Produktionsumgebungen.