Comprendere il rendimento delle query utilizzando la spiegazione delle query

Query Explain ti consente di inviare query Cloud Firestore al backend e ricevere in cambio statistiche dettagliate sulle prestazioni relative all'esecuzione delle query di backend. Funziona come l'operazione EXPLAIN [ANALYZE] in molti sistemi di database relazionali.

Le richieste di Query Explain possono essere inviate utilizzando le librerie client del server 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.

Spiegazione query:

  • Fornisce insight sulla fase di pianificazione dei piani di query in modo da poter modificare gli indici delle query e aumentare l'efficienza.
  • L'opzione Analizza ti aiuta a comprendere i costi e le prestazioni in base alle singole query e ti consente di eseguire rapidamente l'iterazione di diversi pattern di query per ottimizzarne l'utilizzo.

Comprendi le opzioni di Query Explain: predefinita e analisi

Le operazioni di Query Explain possono essere eseguite utilizzando l'opzione predefinita o l'opzione analyze.

Con l'opzione predefinita, Query Explain pianifica la query, ma salta la fase di esecuzione. Verranno restituite le informazioni sulla fase del planner. Puoi utilizzarlo per verificare che una query abbia gli indici necessari e capire quali indici vengono utilizzati. In questo modo, potrai verificare, ad esempio, che una determinata query utilizzi un indice composto anziché dover intersecare molti indici diversi.

Con l'opzione analyze, Query Explain pianifica ed esegue la query. In questo modo vengono restituite tutte le informazioni del planner menzionate in precedenza, insieme alle statistiche del runtime di esecuzione della query. Sono inclusi i dati di fatturazione della query e gli insight a livello di sistema sull'esecuzione della query. Puoi utilizzare questo strumento per testare varie configurazioni di query e indici per ottimizzarne i costi e la latenza.

Quanto costa Spiegazione query?

Quando utilizzi Spiegazione query con l'opzione predefinita, non vengono eseguite operazioni di indicizzazione o lettura. Indipendentemente dalla complessità della query, viene addebitata un'operazione di lettura.

Quando utilizzi Query Explain con l'opzione analyze, vengono eseguite operazioni di indicizzazione e lettura, quindi ti viene addebitato il costo della query come di consueto. Non sono previsti costi aggiuntivi per l'attività di analisi, ma solo il consueto addebito per la query in esecuzione.

Utilizza 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 (Admin)

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 saperne di più, consulta il riferimento al report Query Explain.

Utilizza Spiegazione query con l'opzione ANALYZE

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 (Admin)

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 saperne di più, consulta il riferimento al report Query Explain.

Interpreta i risultati e apporta modifiche

Vediamo uno scenario di esempio in cui eseguiamo query sui film in base al genere e al paese di produzione.

A scopo illustrativo, supponiamo l'equivalente di questa query SQL.

SELECT *
FROM /movies
WHERE category = 'Romantic' AND country = 'USA';

Se utilizziamo l'opzione analyze, le metriche restituite mostrano che la query viene eseguita su due indici a campo singolo, (category ASC, __name__ ASC) e (country ASC, __name__ ASC). Analizza 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 composto completamente coperto (category ASC, country ASC, __name__ ASC).

Eseguendo nuovamente la query con l'opzione ANALYZE, possiamo vedere che l'indice appena creato è selezionato per questa query e che la query viene eseguita in modo molto più rapido ed 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",
               }
    }
}