Auf dieser Seite finden Sie Beispiele für Indexierungsstrategien, die Sie für Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder verwenden können, um Abfragen effizient zu gestalten.
Bevor Sie Ihre Abfragen optimieren, sollten Sie sich mit den zugehörigen Konzepten vertraut machen.
Abfragen mit Query Explain optimieren
Wenn Sie herausfinden möchten, ob Ihre Abfrage und Indexe optimal sind, können Sie Query Explain verwenden, um die Zusammenfassung des Abfrageplans und die Ausführungsstatistiken der Abfrage abzurufen:
Java
Query q = db.collection("employees").whereGreaterThan("salary",
100000).whereGreaterThan("experience", 0);
ExplainResults<QuerySnapshot> explainResults = q.explain(ExplainOptions.builder().analyze(true).build()).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
ExecutionStats executionStats = metrics.getExecutionStats();
System.out.println(planSummary.getIndexesUsed());
System.out.println(stats.getResultsReturned());
System.out.println(stats.getExecutionDuration());
System.out.println(stats.getReadOperations());
System.out.println(stats.getDebugStats());
Node.js
let q = db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">",0);
let options = { analyze : 'true' };
let explainResults = await q.explain(options);
let planSummary = explainResults.metrics.planSummary;
let stats = explainResults.metrics.executionStats;
console.log(planSummary);
console.log(stats);
Im folgenden Beispiel wird gezeigt, wie die Verwendung der richtigen Indexreihenfolge die Anzahl der Indexeinträge reduziert, die von Cloud Firestore gescannt werden.
Einfache Abfragen
Für das vorherige Beispiel mit einer Sammlung von Mitarbeitern sieht die einfache Abfrage, die mit dem Index (experience ASC, salary ASC)
ausgeführt wird, so aus:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
Die Abfrage scannt 95.000 Indexeinträge, um nur fünf Dokumente zurückzugeben. Da das Abfrageprädikat nicht erfüllt ist, werden viele Indexeinträge gelesen, aber herausgefiltert.
// Output query planning info { "indexesUsed": [ { "properties": "(experience ASC, salary ASC, __name__ ASC)", "query_scope": "Collection" } ], // Output Query Execution Stats "resultsReturned": "5", "executionDuration": "2.5s", "readOperations": "100", "debugStats": { "index_entries_scanned": "95000", "documents_scanned": "5", "billing_details": { "documents_billable": "5", "index_entries_billable": "95000", "small_ops": "0", "min_query_cost": "0" } } }
Aus dem fachlichen Know-how können Sie ableiten, dass die meisten Mitarbeiter zumindest eine gewisse Erfahrung haben werden, aber nur wenige ein Gehalt von mehr als 100.000 haben. Anhand dieser Informationen können Sie sehen, dass die Einschränkung salary
selektiver als die Einschränkung experience
ist. Wenn Sie beeinflussen möchten, welcher Index von Cloud Firestore zum Ausführen der Abfrage verwendet wird, geben Sie eine orderBy
-Klausel an, die die salary
-Einschränkung vor der experience
-Einschränkung ordnet.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Wenn Sie die Prädikate explizit mit der orderBy()
-Klausel hinzufügen, verwendet Cloud Firestore den (salary ASC, experience ASC)
-Index, um die Abfrage auszuführen.
Da die Selektivität des ersten Bereichsfilters in dieser Abfrage im Vergleich zur vorherigen Abfrage höher ist, wird sie schneller ausgeführt und ist kosteneffizienter.
// Output query planning info { "indexesUsed": [ { "properties": "(salary ASC, experience ASC, __name__ ASC)", "query_scope": "Collection" } ], // Output Query Execution Stats "resultsReturned": "5", "executionDuration": "0.2s", "readOperations": "6", "debugStats": { "index_entries_scanned": "1000", "documents_scanned": "5", "billing_details": { "documents_billable": "5", "index_entries_billable": "1000", "small_ops": "0", "min_query_cost": "0" } } }