Na tej stronie znajdziesz przykłady strategii indeksowania, których możesz użyć w przypadku zapytań z filtrami zakresu i nierówności w wielu polach, aby zapewnić wydajne działanie zapytań.
Zanim zoptymalizujesz zapytania, zapoznaj się z powiązanymi pojęciami.
Optymalizacja zapytań za pomocą funkcji Query Explain
Aby sprawdzić, czy zapytanie i indeksy są optymalne, możesz użyć Query Explain, aby uzyskać podsumowanie planu zapytania i statystyki wykonania zapytania:
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);
Poniższy przykład pokazuje, jak prawidłowe uporządkowanie indeksu zmniejsza liczbę pozycji indeksu, które skanuje Cloud Firestore.
Proste zapytania
W poprzednim przykładzie kolekcji pracowników proste zapytanie, które działa z indeksem (experience ASC, salary ASC), wygląda tak:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
Zapytanie skanuje 95 000 wpisów indeksu, aby zwrócić tylko 5 dokumentów. Ponieważ predykat zapytania nie jest spełniony, odczytywana jest duża liczba wpisów indeksu, ale są one odfiltrowywane.
// 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" } } }
Na podstawie wiedzy o branży możesz wywnioskować, że większość pracowników ma co najmniej pewne doświadczenie, ale niewielu z nich zarabia więcej niż 100 tys. USD. Z tego wniosku wynika, że ograniczenie salary jest bardziej selektywne niż ograniczenie experience. Aby wpłynąć na indeks, którego Cloud Firestore używa do wykonania zapytania, określ klauzulę orderBy, która porządkuje ograniczenie salary przed ograniczeniem experience.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Jeśli do dodania predykatów użyjesz klauzuli orderBy(),Cloud Firestore użyje indeksu (salary ASC, experience ASC) do uruchomienia zapytania.
W tym zapytaniu selektywność pierwszego filtra zakresu jest wyższa niż w poprzednim zapytaniu, więc zapytanie działa szybciej i jest bardziej opłacalne.
// 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" } } }
Co dalej?
- Dowiedz się więcej o wyjaśnianiu zapytań.
- Dowiedz się więcej o sprawdzonych metodach indeksowania.