Mit Query Explain können Sie Cloud Firestore-Abfragen an das Backend senden und erhalten detaillierte Leistungsstatistiken zur Ausführung der Backend-Abfrage. Er funktioniert wie der Vorgang EXPLAIN [ANALYZE] in vielen relationalen Datenbanksystemen.
Anfragen zur Abfrageerklärung können über die Firestore-Server-Clientbibliotheken gesendet werden.
Anhand der Ergebnisse von Query Explain können Sie nachvollziehen, wie Ihre Abfragen ausgeführt werden. Sie sehen Ineffizienzen und die Position wahrscheinlicher serverseitiger Engpässe.
Query Explain:
- Bietet Statistiken zur Abfrageplanungsphase, damit Sie Ihre Abfrageindexe anpassen und die Effizienz steigern können.
- Mit der Analyseoption können Sie die Kosten und die Leistung pro Abfrage nachvollziehen und schnell verschiedene Abfragemuster durchlaufen, um die Nutzung zu optimieren.
Optionen für Query Explain: Standard und Analyse
Query Explain-Vorgänge können mit der Option default oder analyze ausgeführt werden.
Bei der Standardoption plant Query Explain die Abfrage, überspringt aber die Ausführungsphase. Dadurch werden Informationen zur Planerphase zurückgegeben. Damit können Sie prüfen, ob eine Abfrage die erforderlichen Indexe hat, und feststellen, welche Indexe verwendet werden. So können Sie beispielsweise prüfen, ob für eine bestimmte Abfrage ein zusammengesetzter Index verwendet wird, anstatt viele verschiedene Indexe zu schneiden.
Mit der Option „analyze“ plant und führt Query Explain die Abfrage aus. Dadurch werden alle zuvor erwähnten Planerinformationen zusammen mit Statistiken aus der Laufzeit der Abfrageausführung zurückgegeben. Dazu gehören die Abrechnungsinformationen der Abfrage sowie Informationen auf Systemebene zur Abfrageausführung. Mit diesem Tool können Sie verschiedene Abfrage- und Indexkonfigurationen testen, um deren Kosten und Latenz zu optimieren.
Was kostet Query Explain?
Wenn Sie Query Explain mit der Standardoption verwenden, werden keine Index- oder Lesevorgänge ausgeführt. Unabhängig von der Komplexität der Abfrage wird ein Lesevorgang in Rechnung gestellt.
Wenn Sie Query Explain mit der Option „analyze“ verwenden, werden Index- und Lesevorgänge ausgeführt. Die Abfrage wird Ihnen also wie gewohnt in Rechnung gestellt. Für die Analyseaktivität fallen keine zusätzlichen Kosten an, sondern nur die üblichen Kosten für die ausgeführte Abfrage.
Query Explain mit der Standardoption verwenden
Sie können die Clientbibliotheken verwenden, um eine Anfrage mit Standardoptionen zu senden.
Anfragen werden mit IAM authentifiziert. Dabei werden dieselben Berechtigungen wie für reguläre Abfragevorgänge verwendet. Andere Authentifizierungstechniken wie Firebase Authentication werden ignoriert. Weitere Informationen finden Sie im Leitfaden zu IAM für Server-Clientbibliotheken.
Java (Admin)
Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();
ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
Knoten (Admin)
const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };
const explainResults = await q.explain(options);
const metrics = explainResults.metrics;
const plan = metrics.planSummary;
Das genaue Format der Antwort hängt von der Ausführungsumgebung ab. Die zurückgegebenen Ergebnisse können in JSON konvertiert werden. Beispiel:
{
"indexes_used": [
{"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
{"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
]
}Weitere Informationen finden Sie in der Referenz zum Query Explain-Bericht.
Query Explain mit der Analyseoption verwenden
Sie können die Clientbibliotheken verwenden, um eine Anfrage für eine Analyseoption zu senden.
Anfragen werden mit IAM authentifiziert. Dabei werden dieselben Berechtigungen wie für reguläre Abfragevorgänge verwendet. Andere Authentifizierungstechniken wie Firebase Authentication werden ignoriert. Weitere Informationen finden Sie im Leitfaden zu IAM für Server-Clientbibliotheken.
Java (Admin)
Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();
ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();
Knoten (Admin)
const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'true' };
const explainResults = await q.explain(options);
const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;
Im folgenden Beispiel wird das Objekt stats zusätzlich zu planInfo zurückgegeben.
Das genaue Format der Antwort hängt von der Ausführungsumgebung ab. Die Beispielantwort ist im JSON-Format.
{
"resultsReturned": "5",
"executionDuration": "0.100718s",
"readOperations": "5",
"debugStats": {
"index_entries_scanned": "95000",
"documents_scanned": "5"
"billing_details": {
"documents_billable": "5",
"index_entries_billable": "0",
"small_ops": "0",
"min_query_cost": "0",
}
}
}Weitere Informationen finden Sie in der Referenz zum Query Explain-Bericht.
Ergebnisse interpretieren und Anpassungen vornehmen
Sehen wir uns ein Beispielszenario an, in dem wir Filme nach Genre und Produktionsland abfragen.
Zur Veranschaulichung nehmen wir das Äquivalent dieser SQL-Abfrage an.
SELECT * FROM /movies WHERE category = 'Romantic' AND country = 'USA';
Wenn wir die Option „analyze“ verwenden, zeigen die zurückgegebenen Messwerte, dass die Abfrage für zwei Einzelfeldindexe ausgeführt wird: (category ASC, __name__ ASC) und (country ASC, __name__ ASC). Es werden 16.500 Indexeinträge gescannt, aber nur 1.200 Dokumente zurückgegeben.
// Output query planning info { "indexes_used": [ {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"}, {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"}, ] } // Output query status { "resultsReturned": "1200", "executionDuration": "0.118882s", "readOperations": "1200", "debugStats": { "index_entries_scanned": "16500", "documents_scanned": "1200" "billing_details": { "documents_billable": "1200", "index_entries_billable": "0", "small_ops": "0", "min_query_cost": "0", } } }
Wenn Sie die Leistung der Abfrageausführung optimieren möchten, können Sie einen vollständig abgedeckten zusammengesetzten Index (category ASC, country ASC, __name__ ASC) erstellen.
Wenn wir die Abfrage noch einmal mit der Option „analyze“ ausführen, sehen wir, dass der neu erstellte Index für diese Abfrage ausgewählt wird und die Abfrage viel schneller und effizienter ausgeführt wird.
// Output query planning info { "indexes_used": [ {"query_scope": "Collection", "properties": "(category ASC, country ASC, __name__ ASC)"} ] } // Output query stats { "resultsReturned": "1200", "executionDuration": "0.026139s", "readOperations": "1200", "debugStats": { "index_entries_scanned": "1200", "documents_scanned": "1200" "billing_details": { "documents_billable": "1200", "index_entries_billable": "0", "small_ops": "0", "min_query_cost": "0", } } }