Verwenden Sie zur Fehlerbehebung bei langsamen Abfragen Query Explain, um den Abfrageausführungsplan und das Laufzeitausführungsprofil abzurufen. Im folgenden Abschnitt werden Schritte beschrieben, mit denen Sie die Abfrageleistung je nach Ausführungsprofil optimieren können:
Anzahl der Ergebnisse begrenzen
Anhand des Felds „Zurückgegebene Datensätze“ im Ausführungsbaum können Sie feststellen, 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, wodurch der Speicherbedarf für die Abfrage reduziert wird.
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 Byte-Größ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 abgedeckt sind, kann die Abfrage auch vollständig durch den Indexscan abgedeckt werden, sodass keine Dokumente aus dem primären Speicher abgerufen werden müssen.
Indexe verwenden
So richten Sie Indexe ein und optimieren sie:
Prüfen, ob die Abfrage einen Index verwendet
Sie können feststellen, ob die Abfrage einen Index verwendet, indem Sie die Blattknoten im Ausführungsbaum prüfen. Wenn der Blattknoten des Ausführungsbaums ein TableScan-Knoten ist, bedeutet dies, dass die Abfrage keinen Index verwendet und Dokumente aus dem primären Speicher scannt. 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 seine Feldreihenfolge die Sortieranforderung der Abfrage erfüllen kann.
Wenn ein Index für eine Abfrage verwendet wird, die Abfrage-Engine aber immer noch viele Dokumente abruft und verwirft, was durch einen Scan-Knoten, der viele Datensätze zurückgibt, gefolgt von einem Filterknoten, der wenige Datensätze zurückgibt, 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 dennoch eine Neusortierung des Ergebnissatzes im Arbeitsspeicher durchführt, was durch einen MajorSort-Knoten im Abfrageausführungsbaum angezeigt wird, ist dies ein Zeichen dafür, dass der verwendete Index nicht für die Sortieranforderung der Abfrage verwendet werden kann. 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 Ihre Abfrage Indexe verwenden kann, erstellen Sie reguläre Indexe (keine Multikey-Indexe) mit Feldern in der folgenden Reihenfolge:
- Alle Felder, die in Gleichheitsoperatoren verwendet werden. Um die Wahrscheinlichkeit einer Wiederverwendung über Abfragen hinweg zu maximieren, ordnen Sie die Felder in absteigender Reihenfolge des Vorkommens der Felder in Gleichheitsoperatoren zwischen Abfragen an.
- Alle Felder, nach denen sortiert wird (in derselben Reihenfolge).
- Felder, die in Bereichs- oder Ungleichheitsoperatoren in absteigender Reihenfolge der Selektivität der Abfrageeinschränkung verwendet werden.
- Felder, die als Teil einer Abfrage im Index zurückgegeben werden: Wenn Sie solche Felder in den Index aufnehmen, kann der Index die Abfrage abdecken und es muss kein Dokument aus dem primären Speicher abgerufen werden.
Index- oder Tabellenscan erzwingen
Wenn Sie Cloud Firestore abfragen, werden automatisch alle Indexe verwendet, die die Abfrage wahrscheinlich effizienter machen. Daher müssen Sie für Ihre Abfragen keinen Index angeben. Für Abfragen, die für Ihre Arbeitslast entscheidend sind, empfehlen wir jedoch die Option forceIndex, 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, einen anderen Index für die Abfrage zu verwenden, können Sie den Index mit der Option forceIndex angeben.
Sie können die Option forceIndex in jeder Eingabephase in Pipelinevorgängen verwenden, um den Standardabfrageplan von Cloud Firestore zu überschreiben und einen zu verwendenden Index anzugeben oder einen Tabellenscan zu erzwingen.
Bestimmten Index erzwingen
Wenn Sie die Abfrage dazu zwingen möchten, einen bestimmten Index zu verwenden, geben Sie die Index-ID als String für die Option forceIndex an. Sie finden die Index-ID in der Console oder in Fehlermeldungen.
Im folgenden Beispiel wird der Planer 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 Optimierungstools, wenn die 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 ohne Verwendung sekundärer Indexe gelesen. Wenn Sie einen Tabellenscan erzwingen möchten, setzen Sie forceIndex auf primary.
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 können Sie einen Tabellenscan verwenden:
- Für sehr kleine Sammlungen, bei denen der Index-Overhead nicht gerechtfertigt ist.
- Für Abfragen, die auf die meisten Dokumente in einer Sammlung zugreifen.
- Für die Fehlerbehebung und Leistungsvergleiche.
forceIndex mit Query Explain verwenden
Sie können Query Explain im Modus explain oder 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. - Im
analyze-Modus können Sie die Leistungsmesswerte wie Latenz, gescannte Dokumente und gescannte Indexeinträge mit und ohneforceIndexvergleichen, um die Abfrageleistung zu optimieren.
Best Practices für forceIndex
forceIndex bietet zwar mehr Kontrolle über die Abfrageausführung, der Abfrageoptimierer von Cloud Firestore ist jedoch für die meisten Anwendungsfälle im Allgemeinen effizient.
Beachten Sie bei der Verwendung von forceIndex die folgenden Best Practices:
- 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 ihre Leistungs- und Kostenmerkmale zu verstehen. - Vermeiden Sie die Verwendung von
forceIndex: "primary"für große Sammlungen in Produktionsumgebungen.
Weitere Informationen zur Ausgabe einer Abfrage, die mit Query Explain ausgeführt wurde, finden Sie in der Referenz zur Abfrageausführung.