Ottimizza le query con filtri di intervallo e disuguaglianza su più campi
Questa pagina fornisce esempi della strategia di indicizzazione da utilizzare per le query con filtri di intervallo e disuguaglianza su più campi al fine di creare un'esperienza di query efficiente.
Scopri i concetti correlati prima di ottimizzare le query.
Ottimizza le query con la spiegazione delle query
Per determinare se la query e gli indici utilizzati sono ottimali, puoi utilizzare Query Explain per ottenere il riepilogo del piano di query e le statistiche di esecuzione della query:
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);
L'esempio seguente mostra in che modo l'utilizzo di un ordinamento corretto dell'indice riduce il numero di voci di indice analizzate da Firestore.
Query semplici
Con l'esempio precedente di una raccolta di dipendenti, la semplice query
eseguita con l'indice (experience ASC, salary ASC)
è la seguente:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
La query analizza 95.000 voci di indice solo per restituire cinque documenti. Poiché il predicato della query non è soddisfatto, un numero elevato di voci di indice viene lette, ma filtrate.
// 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" } } }
Dall'esperienza in campo, si può dedurre che la maggior parte dei dipendenti avrà almeno un po' di esperienza, ma pochi avranno uno stipendio superiore a 100.000. Dato questo insight, possiamo concludere che il vincolo salary
è più selettivo del vincolo experience
. Per influenzare l'indice utilizzato da Firestore per eseguire la query, specifica una clausola orderBy
che ordina il vincolo salary
prima del vincolo experience
.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Quando usi esplicitamente la clausola orderBy()
per aggiungere i predicati, Firestore utilizza l'indice (salary ASC, experience ASC)
per eseguire la
query. Di conseguenza, poiché la selettività del filtro del primo intervallo è più elevata in questa query rispetto alla query precedente, la query viene eseguita più velocemente ed è più conveniente.
// 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" } } }
Passaggi successivi
- Scopri di più su Query Explain.
- Scopri di più sulle best practice per l'indicizzazione.