Per risolvere i problemi relativi alle query lente, utilizza Query Explain per ottenere il piano di esecuzione delle query e il profilo di esecuzione del runtime. La sezione seguente descrive i passaggi che puoi seguire per ottimizzare le prestazioni delle query in base al profilo di esecuzione:
Limita il numero di risultati
Utilizza il campo dei 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, le dimensioni dei byte serializzati dei risultati vengono ridotte quando vengono restituiti ai client tramite la 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 in memoria completi con un ordinamento TopN, riducendo i requisiti di memoria per la query.
Limita le dimensioni del documento dei risultati
Valuta la possibilità di limitare le dimensioni del documento restituito utilizzando un select(...) per restituire solo i campi obbligatori o remove_fields(...) per eliminare i campi troppo grandi. In questo modo, si riducono i costi di calcolo e di memoria per l'elaborazione dei risultati intermedi e la dimensione dei byte serializzati dei risultati quando vengono restituiti ai client tramite la rete. Nei casi in cui tutti i campi a cui fa riferimento la query sono coperti da un indice normale, ciò consente anche alla query di essere completamente coperta dalla scansione dell'indice, evitando la necessità di recuperare i documenti dallo spazio di archiviazione principale.
Utilizza gli indici
Segui le istruzioni riportate di seguito per configurare e ottimizzare gli indici.
Identifica 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 analizzando i 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 dell'indice.
Identifica 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 Scan che restituisce molti record seguiti da un nodo Filter che restituisce pochi record, significa 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 riordinamento in memoria del set di risultati, come identificato da un nodo MajorSort nell'albero di esecuzione della query, significa 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 normali (non multichiave) 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à dei vincoli di query.
- Campi che verranno restituiti come parte di una query nell'indice: l'inclusione di questi campi nell'indice consente all'indice di coprire la query ed evita di dover recuperare il documento dallo spazio di archiviazione principale.
Forza una scansione di indice o tabella
Quando esegui una query su Cloud Firestore, vengono utilizzati automaticamente tutti gli indici che potrebbero rendere la query più efficiente. Di conseguenza, non è necessario specificare un indice per le query. Tuttavia, per le query fondamentali per il tuo workload, ti consigliamo di utilizzare l'opzione forceIndex per ottenere prestazioni più coerenti.
In alcuni casi, Cloud Firestore potrebbe scegliere un indice che aumenta la 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 nelle operazioni della pipeline per eseguire l'override del piano di query predefinito di Cloud Firestore e specificare un indice da utilizzare o forzare una scansione della tabella.
Forza 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 lo strumento di pianificazione 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 l'utilizzo di un indice specifico e ottimale per una query.
- Eseguire l'override dell'ottimizzatore 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.
Forza una scansione della tabella
Una scansione della tabella legge i documenti nella raccolta o nel gruppo di raccolte senza utilizzare indici secondari. Per forzare una scansione della 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)
Puoi 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 delle prestazioni.
Utilizza forceIndex con Spiegazione query
Puoi utilizzare Query Explain nelle modalità explain o 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". - Con la modalità
analyze, confronta le metriche sul rendimento, come la latenza, i documenti scansionati e le voci dell'indice scansionate, con e senzaforceIndexper 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 criterio. Se osservi 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 in ambienti di produzione.
Per ulteriori informazioni sull'output di una query eseguita con Query Explain, consulta Riferimento per l'esecuzione delle query.