Ottimizza le query con filtri per intervallo e disuguaglianze su più campi
Questa pagina fornisce esempi di strategie di indicizzazione che puoi utilizzare per le query con filtri per intervallo e disuguaglianza su più campi per creare una un'esperienza di query.
Prima di ottimizzare le query, leggi i concetti correlati.
Ottimizza le query con Query Explain
Per determinare se la query e gli indici sono ottimali, puoi utilizzare Query Spiega per ottenere il riepilogo e le statistiche di esecuzione del piano di query 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 come l'utilizzo dell'ordinamento corretto dell'indice riduce il numero di voci di indice sottoposte a scansione da Firestore.
Query semplici
Con l'esempio precedente di un insieme di dipendenti, la semplice query
eseguito con l'indice (experience ASC, salary ASC)
è il seguente:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
La query analizza solo 95.000 voci di indice per restituire cinque documenti. Poiché la query predicato non è soddisfatto, molte voci di indice vengono lette ma vengono esclusi.
// 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 nel settore si può dedurre che la maggior parte dei dipendenti avrà
ma pochi hanno uno stipendio superiore a 100.000. In base a questa informazione, puoi vedere 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 ordini il vincolo salary
prima del vincolo experience
.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Quando utilizzi esplicitamente la clausola orderBy()
per aggiungere i predicati,
Firestore utilizza l'indice (salary ASC, experience ASC)
per eseguire la query.
Poiché la selettività del filtro del primo intervallo è più alta in questa query
rispetto alla query precedente, la query viene eseguita più velocemente ed è più economica.
// 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.