Per risolvere i problemi relativi alle query lente, utilizza Query Explain per ottenere il piano di esecuzione della query e il profilo di esecuzione runtime. La sezione seguente descrive i passaggi che puoi intraprendere per ottimizzare le prestazioni delle query a seconda del profilo di esecuzione:
Limitare il numero di risultati
Utilizza il campo Record restituiti nell'albero di esecuzione per
identificare se la query restituisce molti documenti. Valuta la possibilità di limitare il numero
di documenti restituiti utilizzando la
fase limit(...). In questo modo si riducono le dimensioni in byte serializzati dei risultati quando vengono restituiti ai client sulla rete. Nei casi
in cui il nodo Limit è preceduto da un nodo MajorSort, il motore di query può
unire i nodi Limit e MajorSort e sostituire una materializzazione e un ordinamento completi in memoria
con un ordinamento TopN, riducendo il requisito di memoria per
la query.
Limitare le dimensioni del documento dei risultati
Valuta la possibilità di limitare le dimensioni del documento restituito utilizzando select(...) per restituire solo i campi richiesti o remove_fields(...) per eliminare i campi troppo grandi. Ciò contribuisce a ridurre il costo di calcolo e memoria dell'elaborazione
dei risultati intermedi e le dimensioni in byte serializzati dei risultati quando vengono restituiti
ai client sulla rete. Nei casi in cui tutti i campi a cui viene fatto riferimento nella query sono coperti da un indice normale, ciò consente anche di coprire completamente la query con la scansione dell'indice, evitando la necessità di recuperare i documenti dallo spazio di archiviazione principale.
Utilizzare gli indici
Segui queste istruzioni per configurare e ottimizzare gli indici.
Identificare se la query utilizza un indice
Puoi identificare se la query utilizza un indice controllando i nodi foglia nell'albero di esecuzione. Se il nodo foglia dell'albero di esecuzione è un nodo TableScan, significa che la query non utilizza un indice e sta eseguendo la scansione dei documenti dallo spazio di archiviazione principale. Se viene utilizzato un indice, il nodo foglia dell'albero di esecuzione mostrerà l'ID indice e i campi indice.
Identificare un indice migliore
Un indice è utile per una query se può ridurre il numero di documenti che il motore di query deve recuperare dallo spazio di archiviazione principale o se l'ordinamento dei campi può soddisfare il requisito di ordinamento della query.
Se un indice viene utilizzato per una query, ma il motore di query recupera e scarta ancora molti documenti, come identificato da un nodo di scansione che restituisce molti record seguito da un nodo di filtro che restituisce pochi record, questo è un segno che il predicato della query soddisfatto utilizzando l'indice non è selettivo. Per creare un indice più adatto, consulta Crea indici.
Se un indice viene utilizzato per una query, ma il motore di query esegue comunque un riordino in memoria del set di risultati, come identificato da un nodo MajorSort nell'albero di esecuzione della query, questo è un segnale che l'indice utilizzato non può essere utilizzato per soddisfare il requisito di ordinamento della query. Per creare un indice più adatto, consulta la sezione successiva.
Crea indici
Segui la documentazione sulla gestione degli indici per creare indici. Per assicurarti che la query possa utilizzare gli indici, crea indici regolari (non Multikey) con i campi nel seguente ordine:
- Tutti i campi che verranno utilizzati negli operatori di uguaglianza. Per massimizzare la possibilità di riutilizzo tra le query, ordina i campi in ordine decrescente di occorrenza dei campi negli operatori di uguaglianza tra le query.
- Tutti i campi in base ai quali verrà eseguito l'ordinamento (nello stesso ordine).
- Campi che verranno utilizzati negli operatori di intervallo o di disuguaglianza in ordine decrescente di selettività del vincolo di query.
- Campi che verranno restituiti nell'ambito di una query nell'indice: l'inclusione di questi campi nell'indice consente all'indice di coprire la query ed evitare di dover recuperare il documento dallo spazio di archiviazione principale.
Forzare una scansione di indice o tabella
Quando esegui una query su Cloud Firestore, vengono utilizzati automaticamente gli indici che
hanno maggiori probabilità di rendere la query più efficiente. Di conseguenza, non devi specificare un indice per le tue query. Tuttavia, per le query critiche
per il tuo carico di lavoro, ti consigliamo di utilizzare l'opzione forceIndex per
un rendimento più coerente.
In alcuni casi, Cloud Firestore potrebbe scegliere un indice che causa un aumento della latenza delle query. Se hai seguito i passaggi per la risoluzione dei problemi relativi alle regressioni delle prestazioni e hai confermato che è opportuno provare un indice diverso per la query, puoi specificare l'indice utilizzando l'opzione forceIndex.
Puoi utilizzare l'opzione forceIndex in qualsiasi fase di input delle operazioni della pipeline per ignorare il piano di query predefinito di Cloud Firestore e specificare un indice da utilizzare o forzare una scansione della tabella.
Forzare un indice specifico
Per forzare la query a utilizzare un indice specifico, fornisci l'ID indice come stringa
all'opzione forceIndex. Puoi trovare l'ID indice nella console o nei messaggi di errore.
L'esempio seguente forza il planner a utilizzare l'indice con ID CICAgOi36pgK:
Node.js
// Force Planner to use Index ID CICAgOi36pgK await db.pipeline() .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" }) .limit(100) .execute();
Java
// Force Planner to use Index ID CICAgOi36pgK Pipeline.Snapshot results1 = firestore.pipeline() .collectionGroup("customers", new CollectionGroupOptions() .withHints(new CollectionHints().withForceIndex("CICAgOi36pgK"))) .limit(100) .execute().get();
Vai
// Force Planner to use Index ID CICAgOi36pgK snapshot1 := client.Pipeline(). CollectionGroup("customers", firestore.WithForceIndex("CICAgOi36pgK")). Limit(100). Execute(ctx)
Ecco alcuni casi d'uso per forzare un indice specifico:
- Testare il rendimento di diversi indici.
- Garantire che per una query venga utilizzato un indice specifico e noto come ottimale.
- Eseguire l'override dello strumento di ottimizzazione quando la sua scelta predefinita non è ottimale per una determinata query.
Se l'indice specificato non viene trovato, la query non va a buon fine.
Forzare la scansione di una tabella
Una scansione della tabella legge i documenti nella raccolta o nel gruppo di raccolte senza
utilizzare indici secondari. Per forzare la scansione di una tabella, imposta forceIndex su primary.
L'esempio seguente forza una scansione della tabella:
// Force Planner to only do a Full-Table Scan
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "primary" })
.limit(100)
Potresti utilizzare una scansione della tabella nei seguenti casi:
- Per raccolte molto piccole in cui l'overhead dell'indice non è giustificato.
- Per le query che accedono alla maggior parte dei documenti di una raccolta.
- Per il debug e i confronti del rendimento.
Utilizzare forceIndex con Spiegazione query
Puoi utilizzare Spiega query, in particolare
con l'opzione analyze, per osservare gli effetti di forceIndex:
- Verifica che Cloud Firestore abbia utilizzato l'indice specificato in
forceIndexcontrollando i nodi foglia dell'albero di esecuzione per l'ID indice. - Verifica che nel piano venga visualizzato un nodo
TableScanquando utilizziforceIndex: "primary". - Confronta le metriche sul rendimento, ad esempio latenza, documenti scansionati e voci
dell'indice scansionate, con e senza
forceIndexper ottimizzare le prestazioni delle query.
Best practice per forceIndex
Sebbene forceIndex offra un maggiore controllo sull'esecuzione delle query,
lo strumento di ottimizzazione delle query di Cloud Firestore è generalmente efficiente per la maggior parte dei casi d'uso.
Quando utilizzi forceIndex, tieni presente le seguenti best practice:
- Utilizza
forceIndexcon giudizio. Se noti prestazioni non ottimali con il piano di query predefinito, utilizza Query Explain per diagnosticare il problema prima di forzare un indice. - Quando utilizzi
forceIndex, assicurati di testare le query con volumi di dati realistici per comprenderne le caratteristiche di prestazioni e costi. - Evita di utilizzare
forceIndex: "primary"su raccolte di grandi dimensioni negli ambienti di produzione.