Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder optimieren
Auf dieser Seite finden Sie Beispiele für Indexierungsstrategien, die bei Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Felder verwendet werden sollten, um eine effiziente Abfrageumgebung zu schaffen.
Informieren Sie sich über die verwandten Konzepte, bevor Sie Ihre Abfragen optimieren.
Abfragen mit Query Explain optimieren
Um festzustellen, ob die verwendete Abfrage und die verwendeten 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 durch die Verwendung der richtigen Indexreihenfolge die Anzahl der Indexeinträge reduziert wird, die Firestore scannt.
Einfache Abfragen
Im vorherigen Beispiel einer Sammlung von Mitarbeitern lautet die einfache Abfrage, die mit dem Index (experience ASC, salary ASC)
ausgeführt wird, so:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
Die Abfrage scannt 95.000 Indexeinträge und gibt nur 5 Dokumente zurück. 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 Domänenwissen können wir ableiten, dass die meisten Mitarbeitenden zumindest ein wenig Erfahrung haben, aber nur wenige ein Gehalt von mehr als 100.000 $ haben werden. Aus diesen Erkenntnissen können wir schließen, dass die Einschränkung salary
selektiver ist als die Einschränkung experience
. Um den Index zu beeinflussen, den Firestore zum Ausführen der Abfrage verwendet, geben Sie eine orderBy
-Klausel an, die die Einschränkung salary
vor der Einschränkung experience
sortiert.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Wenn Sie die Prädikate explizit mit der Klausel orderBy()
hinzufügen, verwendet Firestore den Index (salary ASC, experience ASC)
zum Ausführen der Abfrage. Da die Selektivität des ersten Bereichsfilters bei dieser Abfrage im Vergleich zur vorherigen Abfrage höher ist, wird die Abfrage schneller und kostengünstiger ausgeführt.
// 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" } } }
Weitere Informationen
- Weitere Informationen zu Query Explain
- Best Practices für die Indexierung