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 eine effiziente Abfrage zu ermöglichen.
Bevor Sie Ihre Abfragen optimieren, sollten Sie sich mit den zugehörigen Konzepten vertraut machen.
Abfragen mit Query Explain optimieren
Wenn Sie feststellen möchten, ob Ihre Abfrage und Ihre Indexe optimal sind, können Sie mit Query Explain die Zusammenfassung des Abfrageplans und die Ausführungsstatistiken der Abfrage abrufen:
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);
Das folgende Beispiel zeigt, wie die Verwendung der richtigen Indexreihenfolge die Anzahl der Indexeinträge reduziert, die von Cloud Firestore gescannt werden.
Einfache Abfragen
Im vorherigen Beispiel 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");
Bei der Abfrage werden 95.000 Indexeinträge gescannt, um fünf Dokumente zurückzugeben. Da das Abfrageprädikat nicht erfüllt ist, wird eine große Anzahl von Indexeinträgen 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 Fachwissen können Sie ableiten, dass die meisten Mitarbeiter zumindest etwas Erfahrung haben, aber nur wenige ein Gehalt von mehr als 100.000 haben. Anhand dieser Information können Sie sehen, dass die Einschränkung salary selektiver ist als die Einschränkung experience. Wenn Sie den Index beeinflussen möchten, den Cloud Firestore zum Ausführen der Abfrage verwendet, geben Sie eine orderBy-Klausel an, die die salary-Einschränkung vor der experience-Einschränkung sortiert.
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 Index (salary ASC, experience ASC), um die Abfrage auszuführen.
Da die Selektivität des ersten Bereichsfilters in dieser Abfrage höher ist als in der vorherigen Abfrage, wird die Abfrage schneller ausgeführt und ist kostengünstiger.
// 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" } } }