Comprendere le prestazioni delle query utilizzando Query Explain
Query Explain ti consente di inviare query Firestore in modalità nativa al backend e ricevere in cambio statistiche dettagliate sul rendimento dell'esecuzione delle query di backend. Funziona come l'operazione EXPLAIN [ANALYZE]
in molti
sistemi di database relazionali.
Le richieste Query Explain possono essere inviate utilizzando le librerie client server di Firestore.
I risultati di Query Explain ti aiutano a capire come vengono eseguite le query, mostrandoti le inefficienze e la posizione dei probabili colli di bottiglia lato server.
Query Explain:
- Fornisce informazioni sulla fase di pianificazione delle query per consentirti di modificare gli indici delle query e aumentare l'efficienza.
- L'utilizzo dell'opzione di analisi ti aiuta a comprendere i costi e il rendimento in base alle query e ti consente di scorrere rapidamente diversi pattern di query per ottimizzarne l'utilizzo.
Comprendere le opzioni di spiegazione delle query: predefinita e analizza
Le operazioni Query Explain possono essere eseguite utilizzando l'opzione predefinita o l'opzione analizza.
Con l'opzione predefinita, Query Explain pianifica la query, ma salta la fase di esecuzione. Verranno restituite le informazioni sulla fase di pianificazione. Puoi utilizzarlo per verificare che una query abbia gli indici necessari e capire quali indici vengono utilizzati. In questo modo, ad esempio, puoi verificare che una determinata query utilizzi un indice composto anziché dover intersecare molti indici diversi.
Con l'opzione di analisi, Query Explain pianifica ed esegue la query. Vengono restituite tutte le informazioni sul planner menzionate in precedenza, insieme alle statistiche del runtime di esecuzione della query. Queste informazioni includeranno i dati di fatturazione della query, nonché approfondimenti a livello di sistema sull'esecuzione della query. Puoi utilizzare questi strumenti per testare varie configurazioni di query e indici per ottimizzare il costo e la latenza.
Quanto costa Query Explain?
Quando utilizzi Query Explain con l'opzione predefinita, non vengono eseguite operazioni di indice o di lettura. Indipendentemente dalla complessità della query, viene addebitata un'operazione di lettura.
Quando utilizzi Query Explain con l'opzione di analisi, vengono eseguite operazioni di lettura e indice, pertanto la query ti viene addebitata come di consueto. Non sono previsti costi aggiuntivi per l'attività di analisi, ma solo l'addebito consueto per la query eseguita.
Utilizzare Query Explain con l'opzione predefinita
Puoi utilizzare le librerie client per inviare una richiesta di opzione predefinita.
Tieni presente che le richieste vengono autenticate con IAM, utilizzando le stesse autorizzazioni per le normali operazioni di query. Altre tecniche di autenticazione, come Firebase Authentication, vengono ignorate. Per saperne di più, consulta la guida su IAM per le librerie client server.
Java (amministratore)
Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();
ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
Nodo (amministratore)
const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };
const explainResults = await q.explain(options);
const metrics = explainResults.metrics;
const plan = metrics.planSummary;
Il formato esatto della risposta dipende dall'ambiente di esecuzione. I risultati restituiti possono essere convertiti in JSON. Ad esempio:
{ "indexes_used": [ {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"}, {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"}, ] }
Per maggiori informazioni, consulta il riferimento al report Query Explain.
Utilizzare Query Explain con l'opzione di analisi
Puoi utilizzare le librerie client per inviare una richiesta di opzione di analisi.
Tieni presente che le richieste vengono autenticate con IAM, utilizzando le stesse autorizzazioni per le normali operazioni di query. Altre tecniche di autenticazione, come Firebase Authentication, vengono ignorate. Per saperne di più, consulta la guida su IAM per le librerie client server.
Java (amministratore)
Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();
ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();
Nodo (amministratore)
const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'true' };
const explainResults = await q.explain(options);
const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;
L'esempio seguente mostra l'oggetto stats
restituito oltre a planInfo
.
Il formato esatto della risposta dipende dall'ambiente di esecuzione. La
risposta di esempio è in formato JSON.
{ "resultsReturned": "5", "executionDuration": "0.100718s", "readOperations": "5", "debugStats": { "index_entries_scanned": "95000", "documents_scanned": "5" "billing_details": { "documents_billable": "5", "index_entries_billable": "0", "small_ops": "0", "min_query_cost": "0", } } }
Per maggiori informazioni, consulta il riferimento al report Query Explain.
Interpretare i risultati e apportare modifiche
Esaminiamo uno scenario di esempio in cui eseguiamo una query sui film per genere e paese di produzione.
A titolo illustrativo, supponiamo l'equivalente di questa query SQL.
SELECT * FROM /movies WHERE category = 'Romantic' AND country = 'USA';
Se utilizziamo l'opzione di analisi, le metriche restituite mostrano che la query
viene eseguita su due indici a un solo campo, (category ASC, __name__ ASC)
e
(country ASC, __name__ ASC)
. Esegue la scansione di 16.500 voci di indice, ma restituisce
solo 1200 documenti.
// Output query planning info { "indexes_used": [ {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"}, {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"}, ] } // Output query status { "resultsReturned": "1200", "executionDuration": "0.118882s", "readOperations": "1200", "debugStats": { "index_entries_scanned": "16500", "documents_scanned": "1200" "billing_details": { "documents_billable": "1200", "index_entries_billable": "0", "small_ops": "0", "min_query_cost": "0", } } }
Per ottimizzare le prestazioni di esecuzione della query, puoi creare un indice composito completamente coperto (category ASC, country ASC, __name__ ASC)
.
Se esegui di nuovo la query con l'opzione di analisi, puoi notare che l'indice appena creato è selezionato per questa query e che la query viene eseguita molto più velocemente e in modo più efficiente.
// Output query planning info { "indexes_used": [ {"query_scope": "Collection", "properties": "(category ASC, country ASC, __name__ ASC)"} ] } // Output query stats { "resultsReturned": "1200", "executionDuration": "0.026139s", "readOperations": "1200", "debugStats": { "index_entries_scanned": "1200", "documents_scanned": "1200" "billing_details": { "documents_billable": "1200", "index_entries_billable": "0", "small_ops": "0", "min_query_cost": "0", } } }