Piano di query e cronologia

Incorporato nei job di query, BigQuery include il piano di query diagnostico e i tempi di esecuzione. Queste informazioni sono simili a quelle fornite da istruzioni come EXPLAIN in altri sistemi di database e analisi. Queste informazioni possono essere recuperate dalle risposte API di metodi come jobs.get.

Per le query a esecuzione prolungata, BigQuery aggiornerà periodicamente queste statistiche. Questi aggiornamenti vengono eseguiti indipendentemente dalla frequenza con cui viene eseguito il polling dello stato del job, ma in genere non vengono eseguiti più di una volta ogni 30 secondi. Inoltre, i job di query che non utilizzano risorse di esecuzione, come richieste di prova o risultati che possono essere forniti dai risultati memorizzati nella cache, non includono le informazioni diagnostiche aggiuntive, anche se potrebbero essere presenti altre statistiche.

Sfondo

Quando BigQuery esegue una query, converte l'SQL in un grafico di esecuzione composto da fasi. Le fasi sono composte da passaggi, le operazioni elementari che eseguono la logica della query. BigQuery utilizza un'architettura parallela altamente distribuita che esegue le fasi in parallelo per ridurre la latenza. Le fasi comunicano tra loro utilizzando shuffle, un'architettura di memoria distribuita veloce.

Il piano di query utilizza i termini unità di lavoro e worker per descrivere il parallelismo della fase. In altre parti di BigQuery, potresti incontrare il termine slot, che è una rappresentazione astratta di più aspetti dell'esecuzione delle query, tra cui risorse di calcolo, memoria e I/O. Gli slot eseguono in parallelo le singole unità di lavoro di una fase. Le statistiche dei job di primo livello forniscono il costo della singola query utilizzando totalSlotMs in base a questa contabilità astratta.

Un'altra proprietà importante dell'esecuzione delle query è che BigQuery può modificare il piano di query durante l'esecuzione di una query. Ad esempio, BigQuery introduce le fasi di ripartizione per migliorare la distribuzione dei dati tra i worker di query, il che migliora il parallelismo e riduce la latenza delle query.

Oltre al piano di query, i job di query mostrano anche una cronologia di esecuzione, che fornisce un conteggio delle unità di lavoro completate, in attesa e attive. Una query può avere più fasi con worker attivi contemporaneamente e la sequenza temporale ha lo scopo di mostrare l'avanzamento complessivo della query.

Visualizza il grafico di esecuzione con la console Cloud de Confiance

Nella consoleCloud de Confiance , puoi visualizzare i dettagli del piano di query per una query completata facendo clic sul pulsante Dettagli esecuzione.

Il piano di query.

Informazioni sul piano di query

All'interno della risposta dell'API, i piani di query sono rappresentati come un elenco di fasi della query. Ogni elemento dell'elenco mostra statistiche di riepilogo per fase, informazioni dettagliate sui passaggi e classificazioni dei tempi delle fasi. Non tutti i dettagli vengono visualizzati nella console Cloud de Confiance , ma possono essere tutti presenti nelle risposte API.

Informazioni sul grafico di esecuzione

Nella console Cloud de Confiance , puoi visualizzare i dettagli del piano di query facendo clic sulla scheda Grafico di esecuzione.

La scheda del grafico di esecuzione.

Il riquadro Grafico di esecuzione è organizzato nel seguente modo:

Il layout del grafico di esecuzione.

  • Al centro si trova il grafico di esecuzione. Mostra le fasi come nodi e la memoria di rimescolamento scambiata tra le fasi come archi.
  • Nel riquadro a sinistra è presente la heatmap del testo della query. Mostra il testo della query principale che la query ha eseguito insieme a tutte le viste a cui fa riferimento.
  • Il riquadro a destra contiene i dettagli della query o dello stage.

Il grafico di esecuzione applica uno schema di colori ai nodi in base al tempo di slot, in cui i nodi di colore rosso più scuro richiedono più tempo di slot rispetto al resto delle fasi del grafico.

Per navigare nel grafico di esecuzione, puoi:

  • Fai clic e tieni premuto sullo sfondo del grafico per spostarti in diverse aree del grafico.
  • Utilizza la rotellina del mouse per aumentare e diminuire lo zoom del grafico.
  • Fai clic e tieni premuto sulla minimappa in alto a destra per spostarti in diverse aree del grafico.

Se fai clic su una fase nel grafico, vengono visualizzati i dettagli della fase selezionata. I dettagli della fase includono:

  • Statistiche. Per informazioni dettagliate sulle statistiche, consulta la panoramica dello stadio.
  • Dettagli del passaggio. I passaggi descrivono le singole operazioni che eseguono la logica della query.

Dettagli del passaggio

Le fasi sono costituite da passaggi, le singole operazioni che eseguono la logica della query. I passaggi hanno sottopassaggi che descrivono cosa ha fatto il passaggio in pseudocodice. I passaggi secondari utilizzano le variabili per descrivere le relazioni tra i passaggi. Le variabili iniziano con un segno del dollaro seguito da un numero univoco. I numeri delle variabili non vengono condivisi tra le fasi.

L'immagine seguente mostra i passaggi di una fase:

I dettagli del passaggio del grafico di esecuzione.

Ecco un esempio dei passaggi di una fase:

  READ
  $30:l_orderkey, $31:l_quantity
  FROM lineitem

  AGGREGATE
  GROUP BY $100 := $30
  $70 := SUM($31)

  WRITE
  $100, $70
  TO __stage00_output
  BY HASH($100)

I passaggi dell'esempio descrivono quanto segue:

  • Lo stage ha letto le colonne l_orderkey e l_quantity dalla tabella lineitem e ha memorizzato i valori nelle variabili $30 e $31, rispettivamente.
  • Lo stage ha aggregato le variabili $30 e $31, memorizzando le aggregazioni nelle variabili $100 e $70, rispettivamente.
  • Lo stage ha scritto i risultati delle variabili $100 e $70 da rimescolare. Lo stage ha ordinato i risultati nella memoria casuale in base a 100 $.

Consulta la sezione Interpretare e ottimizzare i passaggi per informazioni dettagliate sul tipo di passaggi e su come ottimizzarli.

BigQuery potrebbe troncare i passaggi secondari quando il grafico di esecuzione della query era sufficientemente complesso da causare problemi di dimensioni del payload durante il recupero delle informazioni sulla query.

Mappa termica del testo della query

Per richiedere un feedback o assistenza per questa funzionalità, invia un'email all'indirizzo bq-performance-troubleshooting+feedback@google.com

BigQuery può mappare alcuni passaggi della fase a parti del testo della query. La mappa termica del testo della query mostra tutto il testo della query corrispondente con i passaggi della fase. Evidenzia il testo della query in base al tempo di slot totale delle fasi i cui passaggi hanno mappato il testo della query.

L'immagine seguente mostra il testo della query evidenziato:

Il testo della query evidenziato nel grafico di esecuzione.

Se tieni il puntatore sopra una parte mappata del testo della query, viene visualizzata una descrizione comando che elenca tutti i passaggi della fase mappati al testo della query insieme all'intervallo di tempo della fase. Se fai clic su un testo della query mappato, viene selezionata la fase nel grafico di esecuzione e vengono aperti i dettagli della fase nel riquadro a destra.

Il grafico di esecuzione associa il testo della query alla fase.

Una singola parte del testo della query può essere mappata a più fasi. La descrizione comando elenca ogni fase mappata e il relativo orario dello slot. Se fai clic sul testo della query, vengono evidenziate le fasi corrispondenti e il resto del grafico viene visualizzato in grigio. Se fai clic su una fase specifica, vengono visualizzati i relativi dettagli.

L'immagine seguente mostra la relazione tra il testo della query e i dettagli del passaggio:

Il grafico di esecuzione associa il testo della query al passaggio.

Nella sezione Dettagli passaggio di una fase, se un passaggio viene mappato al testo della query, il passaggio ha un'icona di codice. Se fai clic sull'icona del codice, viene evidenziata la parte mappata del testo della query a sinistra.

È importante tenere presente che il colore della mappa di calore si basa sull'intera durata dello slot della fase. Poiché BigQuery non misura il tempo slot dei passaggi, la mappa termica non rappresenta il tempo slot effettivo per quella porzione specifica di testo della query mappato. Nella maggior parte dei casi, una fase esegue un solo passaggio complesso, ad esempio un'unione o un'aggregazione. Pertanto, il colore della mappa termica è appropriato. Tuttavia, quando una fase è composta da passaggi che eseguono più operazioni complesse, il colore della mappa termica potrebbe rappresentare in modo eccessivo il tempo di slot effettivo nella mappa termica. In questi casi, è importante comprendere gli altri passaggi che compongono la fase per ottenere una comprensione più completa del rendimento della query.

Panoramica dello stage

I campi di riepilogo per ogni fase possono includere quanto segue:

Campo API Descrizione
id ID numerico univoco per lo stato.
name Nome riepilogativo semplice per la fase. Il steps all'interno della fase fornisce ulteriori dettagli sui passaggi di esecuzione.
status Stato di esecuzione della fase. Gli stati possibili sono PENDING, RUNNING, COMPLETE, FAILED e CANCELLED.
inputStages Un elenco degli ID che formano il grafico delle dipendenze della fase. Ad esempio, una fase JOIN spesso richiede due fasi dipendenti che preparano i dati sul lato sinistro e destro della relazione JOIN.
startMs Timestamp, in millisecondi dell'epoca, che rappresenta il momento in cui è iniziata l'esecuzione del primo worker all'interno della fase.
endMs Timestamp, in millisecondi dell'epoca, che rappresenta il momento in cui l'ultimo worker ha completato l'esecuzione.
steps Un elenco più dettagliato dei passaggi di esecuzione all'interno della fase. Per saperne di più, consulta la sezione successiva.
recordsRead Dimensione dell'input della fase come numero di record, in tutti i worker della fase.
recordsWritten Dimensione dell'output dello stage come numero di record, in tutti i worker dello stage.
parallelInputs Numero di unità di lavoro parallelizzabili per la fase. A seconda della fase e della query, questo valore può rappresentare il numero di segmenti colonnari all'interno di una tabella o il numero di partizioni all'interno di un rimescolamento intermedio.
completedParallelInputs Numero di unità di lavoro all'interno della fase che sono state completate. Per alcune query, non è necessario completare tutti gli input all'interno di una fase per completarla.
shuffleOutputBytes Rappresenta il totale dei byte scritti in tutti i worker all'interno di una fase della query.
shuffleOutputBytesSpilled Le query che trasmettono una quantità significativa di dati tra le fasi potrebbero dover ricorrere alla trasmissione basata su disco. La statistica dei byte con overflow comunica la quantità di dati con overflow su disco. Dipende da un algoritmo di ottimizzazione, quindi non è deterministico per una determinata query.

Classificazione dei tempi per fase

Le fasi della query forniscono classificazioni temporali delle fasi, in forma relativa e assoluta. Poiché ogni fase di esecuzione rappresenta il lavoro svolto da uno o più worker indipendenti, le informazioni vengono fornite sia in termini di tempi medi che di tempi nel caso peggiore. Questi tempi rappresentano le prestazioni medie di tutti i worker in una fase, nonché le prestazioni del worker più lento della coda lunga per una determinata classificazione. I tempi medi e massimi sono ulteriormente suddivisi in rappresentazioni assolute e relative. Per le statistiche basate sul rapporto, i dati vengono forniti come frazione del tempo più lungo trascorso da qualsiasi lavoratore in qualsiasi segmento.

La console Cloud de Confiance presenta la tempistica dello spettacolo utilizzando le rappresentazioni relative della tempistica.

Le informazioni sul tempo di esecuzione delle fasi vengono riportate come segue:

Tempi relativi Temporizzazione assoluta Numeratore del rapporto
waitRatioAvg waitMsAvg Tempo medio trascorso da un lavoratore in attesa di essere programmato.
waitRatioMax waitMsMax Tempo trascorso in attesa della pianificazione dal worker più lento.
readRatioAvg readMsAvg Tempo impiegato dal lavoratore medio per leggere i dati di input.
readRatioMax readMsMax Tempo impiegato dal worker più lento per leggere i dati di input.
computeRatioAvg computeMsAvg Tempo medio trascorso dal worker con la CPU vincolata.
computeRatioMax computeMsMax Tempo in cui il worker più lento ha utilizzato la CPU.
writeRatioAvg writeMsAvg Tempo impiegato dal worker medio per scrivere i dati di output.
writeRatioMax writeMsMax Tempo impiegato dal worker più lento per scrivere i dati di output.

Panoramica del passaggio

I passaggi contengono le operazioni eseguite da ogni worker all'interno di una fase, presentate come un elenco ordinato di operazioni. Ogni operazione di passaggio ha una categoria e alcune operazioni forniscono informazioni più dettagliate. Le categorie di operazioni presenti nel piano di query includono quanto segue:

Categoria del passaggio Descrizione
READ Lettura di una o più colonne da una tabella di input o da uno shuffling intermedio. Nei dettagli del passaggio vengono restituite solo le prime sedici colonne lette.
WRITE Scrittura di una o più colonne in una tabella di output o in uno shuffling intermedio. Per gli output partizionati HASH di una fase, sono incluse anche le colonne utilizzate come chiave di partizione.
COMPUTE Valutazione delle espressioni e funzioni SQL.
FILTER Utilizzato dalle clausole WHERE, OMIT IF e HAVING.
SORT ORDER BY che include le chiavi di colonna e l'ordine di ordinamento.
AGGREGATE Implementa le aggregazioni per clausole come GROUP BY o COUNT, tra le altre.
LIMIT Implementa la clausola LIMIT.
JOIN Implementa i join per clausole come JOIN, tra le altre; include il tipo di join e possibilmente le condizioni di join.
ANALYTIC_FUNCTION Un'invocazione di una funzione finestra (nota anche come "funzione analitica").
USER_DEFINED_FUNCTION Un'invocazione a una funzione definita dall'utente'utente.

Comprendere i passaggi con il testo della query

Per assistenza durante l'anteprima, invia un'email all'indirizzo bq-query-inspector-feedback@google.com.

Comprendere la relazione tra i passaggi della fase e la query può essere difficile. La sezione Testo della query mostra la relazione tra alcuni passaggi e il testo della query originale.

La sezione Testo della query evidenzia diverse parti del testo della query originale e mostra i passaggi che rimandano al testo della query immediatamente precedente al testo della query originale evidenziato. Solo i passaggi immediatamente sopra una parte evidenziata del testo della query originale si applicano al testo della query evidenziata.

Il grafico di esecuzione con il testo della query
della fase.

L'esempio di screenshot mostra questi mapping:

  • Il passaggio AGGREGATE: GROUP BY $100 := $30 corrisponde al testo della query select l_orderkey.

  • Il passaggio READ: FROM lineitem corrisponde al testo della query select ... from lineitem.

  • Il passaggio AGGREGATE: $70 := SUM($31) corrisponde al testo della query sum(l_quantity).

Non tutti i passaggi possono essere mappati nuovamente al testo della query.

Se una query utilizza le viste e se i passaggi della fase hanno mappature al testo della query di una vista, la sezione Testo della query mostra il nome della vista e il testo della query della vista con le relative mappature. Tuttavia, se la visualizzazione viene eliminata o se perdi l'bigquery.tables.get autorizzazione IAM per la visualizzazione, la sezione Testo della query non mostra le mappature delle fasi dello stage per la visualizzazione.

Interpretare e ottimizzare i passaggi

Le sezioni seguenti spiegano come interpretare i passaggi di un piano di query e forniscono modi per ottimizzare le query.

READ passaggio

Il passaggio READ indica che una fase sta accedendo ai dati per l'elaborazione. I dati possono essere letti direttamente dalle tabelle a cui viene fatto riferimento in una query o dalla memoria di shuffling. Quando vengono letti i dati di una fase precedente, BigQuery legge i dati dalla memoria di shuffling. La quantità di dati scansionati influisce sui costi quando utilizzi slot on demand e sulle prestazioni quando utilizzi le prenotazioni.

Potenziali problemi di rendimento

  • Scansione di grandi dimensioni di una tabella non partizionata: se la query richiede solo una piccola porzione dei dati, ciò potrebbe indicare che una scansione della tabella è inefficiente. Il partizionamento potrebbe essere una buona strategia di ottimizzazione.
  • Scansione di una tabella di grandi dimensioni con un piccolo rapporto di filtro:ciò suggerisce che il filtro non riduce in modo efficace i dati scansionati. Valuta la possibilità di rivedere le condizioni del filtro.
  • Byte di shuffling riversati su disco:questo suggerisce che i dati non sono memorizzati in modo efficace utilizzando tecniche di ottimizzazione come il clustering, che potrebbe mantenere dati simili nei cluster.

Ottimizza

  • Filtro mirato:utilizza le clausole WHERE in modo strategico per filtrare i dati irrilevanti il prima possibile nella query. In questo modo si riduce la quantità di dati che devono essere elaborati dalla query.
  • Partizionamento e clustering:BigQuery utilizza il partizionamento e il clustering delle tabelle per individuare in modo efficiente segmenti di dati specifici. Assicurati che le tabelle siano partizionate e raggruppate in cluster in base ai pattern di query tipici per ridurre al minimo i dati scansionati durante i passaggi READ.
  • Seleziona le colonne pertinenti:evita di utilizzare le istruzioni SELECT *. Seleziona invece colonne specifiche o utilizza SELECT * EXCEPT per evitare di leggere dati non necessari.
  • Viste materializzate:le viste materializzate possono precalcolare e archiviare aggregazioni utilizzate di frequente, riducendo potenzialmente la necessità di leggere le tabelle di base durante i passaggi READ per le query che utilizzano queste viste.

COMPUTE passaggio

Nel passaggio COMPUTE, BigQuery esegue le seguenti azioni sui tuoi dati:

  • Valuta le espressioni nelle clausole SELECT, WHERE, HAVING e altre della query, inclusi calcoli, confronti e operazioni logiche.
  • Esegue funzioni SQL integrate e funzioni definite dall'utente.
  • Filtra le righe di dati in base alle condizioni della query.

Ottimizza

Il piano di query può rivelare i colli di bottiglia nel passaggio COMPUTE. Cerca le fasi con calcoli estesi o un numero elevato di righe elaborate.

  • Correlare il passaggio COMPUTE al volume di dati:se una fase mostra un calcolo significativo ed elabora un grande volume di dati, potrebbe essere un buon candidato per l'ottimizzazione.
  • Dati distorti:per le fasi in cui il massimo di calcolo è significativamente superiore alla media di calcolo, ciò indica che la fase ha trascorso una quantità di tempo sproporzionata per l'elaborazione di alcune sezioni di dati. Valuta la distribuzione dei dati per verificare se sono disallineati.
  • Considera i tipi di dati:utilizza i tipi di dati appropriati per le colonne. Ad esempio, l'utilizzo di numeri interi, date e ore e timestamp anziché stringhe può migliorare le prestazioni.

WRITE passaggio

WRITE passaggi vengono eseguiti per i dati intermedi e l'output finale.

  • Scrittura nella memoria di shuffling:in una query in più fasi, il passaggio WRITE spesso comporta l'invio dei dati elaborati a un'altra fase per un'ulteriore elaborazione. Ciò è tipico della memoria di shuffling, che combina o aggrega dati provenienti da più origini. I dati scritti durante questa fase sono in genere un risultato intermedio, non l'output finale.
  • Output finale:il risultato della query viene scritto nella destinazione o in una tabella temporanea.

Partizionamento hash

Quando una fase del piano di query scrive dati in un output partizionato con hash, BigQuery scrive le colonne incluse nell'output e la colonna scelta come chiave di partizionamento.

Ottimizza

Anche se il passaggio WRITE potrebbe non essere ottimizzato direttamente, comprenderne il ruolo può aiutarti a identificare potenziali colli di bottiglia nelle fasi precedenti:

  • Ridurre al minimo i dati scritti:concentrati sull'ottimizzazione delle fasi precedenti con il filtraggio e l'aggregazione per ridurre la quantità di dati scritti durante questo passaggio.
  • Partizionamento:la scrittura trae grande vantaggio dal partizionamento delle tabelle. Se i dati che scrivi sono limitati a partizioni specifiche, BigQuery può eseguire scritture più rapide.

    Se l'istruzione DML ha una clausola WHERE con una condizione statica rispetto a una colonna di partizione della tabella, BigQuery modifica solo le partizioni della tabella pertinenti.

  • Compromessi della denormalizzazione:la denormalizzazione a volte può portare a set di risultati più piccoli nel passaggio intermedio WRITE. Tuttavia, ci sono svantaggi come un maggiore utilizzo dello spazio di archiviazione e problemi di coerenza dei dati.

JOIN passaggio

Nel passaggio JOIN, BigQuery combina i dati di due origini dati. I join possono includere condizioni di join. I join richiedono molte risorse. Quando esegui il join di grandi quantità di dati in BigQuery, le chiavi di join vengono rimescolate in modo indipendente per allinearsi allo stesso slot, in modo che il join venga eseguito localmente su ogni slot.

Il piano di query per il passaggio JOIN in genere rivela i seguenti dettagli:

  • Pattern di join: indica il tipo di join utilizzato. Ogni tipo definisce il numero di righe delle tabelle unite incluse nel set di risultati.
  • Colonne di unione:sono le colonne utilizzate per abbinare le righe tra le origini dati. La scelta delle colonne è fondamentale per il rendimento del join.

Pattern di unione

  • Broadcast join:quando una tabella, in genere quella più piccola, può essere inserita nella memoria di un singolo nodo worker o slot, BigQuery può trasmetterla a tutti gli altri nodi per eseguire il join in modo efficiente. Cerca JOIN EACH WITH ALL nei dettagli del passaggio.
  • Unione hash:quando le tabelle sono grandi o un'unione broadcast non è adatta, potrebbe essere utilizzata un'unione hash. BigQuery utilizza operazioni di hashing e rimescolamento per rimescolare le tabelle sinistra e destra in modo che le chiavi corrispondenti finiscano nello stesso slot per eseguire un join locale. I join hash sono un'operazione costosa poiché i dati devono essere spostati, ma consentono una corrispondenza efficiente delle righe tra gli hash. Cerca JOIN EACH WITH EACH nei dettagli del passaggio.
  • Self-join:un anti-pattern SQL in cui una tabella viene unita a se stessa.
  • Cross join:un antipattern SQL che può causare problemi di prestazioni significativi perché genera dati di output più grandi rispetto agli input.
  • Join asimmetrico: la distribuzione dei dati nella chiave di join di una tabella è molto asimmetrica e può causare problemi di prestazioni. Cerca i casi in cui il tempo di calcolo massimo è molto maggiore del tempo di calcolo medio nel piano di query. Per ulteriori informazioni, consulta Join ad alta cardinalità e Skew della partizione.

Debug

  • Volume elevato di dati:se il piano di query mostra una quantità significativa di dati elaborati durante il passaggio JOIN, esamina la condizione di join e le chiavi di join. Valuta la possibilità di filtrare o utilizzare chiavi di unione più selettive.
  • Distribuzione dei dati asimmetrica:analizza la distribuzione dei dati delle chiavi di unione. Se una tabella è molto distorta, esplora strategie come la suddivisione della query o il prefiltraggio.
  • Join con cardinalità elevata:i join che producono molte più righe rispetto al numero di righe di input a sinistra e a destra possono ridurre drasticamente le prestazioni delle query. Evita i join che producono un numero molto elevato di righe.
  • Ordine errato della tabella:assicurati di aver scelto il tipo di join appropriato, ad esempio INNER o LEFT, e di aver ordinato le tabelle dalla più grande alla più piccola in base ai requisiti della query.

Ottimizza

  • Chiavi di join selettive:per le chiavi di join, utilizza INT64 anziché STRING quando possibile. I confronti STRING sono più lenti dei confronti INT64 perché confrontano ogni carattere di una stringa. I numeri interi richiedono un solo confronto.
  • Filtra prima dell'unione:applica i filtri della clausola WHERE alle singole tabelle prima dell'unione. In questo modo, la quantità di dati coinvolti nell'operazione di join viene ridotta.
  • Evita le funzioni nelle colonne di unione:evita di chiamare le funzioni nelle colonne di unione. Standardizza invece i dati delle tabelle durante la procedura di importazione o post-importazione utilizzando pipeline SQL ELT. Questo approccio elimina la necessità di modificare dinamicamente le colonne di unione, il che consente unioni più efficienti senza compromettere l'integrità dei dati.
  • Evita i self-join:i self-join vengono comunemente utilizzati per calcolare le relazioni dipendenti dalle righe. Tuttavia, i self-join possono potenzialmente quadruplicare il numero di righe di output, causando problemi di prestazioni. Anziché fare affidamento sui self-join, valuta la possibilità di utilizzare le funzioni finestra (analitiche).
  • Prima le tabelle di grandi dimensioni:anche se l'ottimizzatore di query SQL può determinare quale tabella deve trovarsi su quale lato dell'unione, ordina le tabelle unite in modo appropriato. La best practice consiste nel posizionare prima la tabella più grande, poi quella più piccola e poi quelle di dimensioni decrescenti.
  • Denormalizzazione:in alcuni casi, la denormalizzazione strategica delle tabelle (aggiunta di dati ridondanti) può eliminare completamente i join. Tuttavia, questo approccio comporta compromessi in termini di archiviazione e coerenza dei dati.
  • Partizionamento e clustering: il partizionamento delle tabelle in base alle chiavi di join e il clustering dei dati collocati possono velocizzare notevolmente i join consentendo a BigQuery di scegliere come target le partizioni di dati pertinenti.
  • Ottimizzazione dei join asimmetrici: per evitare problemi di prestazioni associati ai join asimmetrici, prefiltra i dati della tabella il prima possibile o suddividi la query in due o più query.

AGGREGATE passaggio

Nel passaggio AGGREGATE, BigQuery aggrega e raggruppa i dati.

Debug

  • Dettagli fase:controlla il numero di righe di input e di output dell'aggregazione e la dimensione del rimescolamento per determinare la riduzione dei dati ottenuta dal passaggio di aggregazione e se è stato coinvolto il data shuffling.
  • Dimensione shuffle:una dimensione shuffle elevata potrebbe indicare che una quantità significativa di dati è stata spostata tra i nodi worker durante l'aggregazione.
  • Controlla la distribuzione dei dati:assicurati che i dati siano distribuiti in modo uniforme tra le partizioni. La distribuzione distorta dei dati può comportare carichi di lavoro sbilanciati nel passaggio di aggregazione.
  • Rivedi le aggregazioni: analizza le clausole di aggregazione per verificare che siano necessarie ed efficienti.

Ottimizza

  • Clustering:raggruppa le tabelle in cluster in base alle colonne utilizzate di frequente in GROUP BY, COUNT o altre clausole di aggregazione.
  • Partizionamento:scegli una strategia di partizionamento in linea con i tuoi pattern di query. Valuta la possibilità di utilizzare tabelle partizionate per data di importazione per ridurre la quantità di dati scansionati durante l'aggregazione.
  • Aggrega prima:se possibile, esegui le aggregazioni prima nella pipeline di query. In questo modo è possibile ridurre la quantità di dati da elaborare durante l'aggregazione.
  • Ottimizzazione del rimescolamento: se il rimescolamento è un collo di bottiglia, esplora i modi per ridurlo al minimo. Ad esempio, denormalizza le tabelle o utilizza il clustering per collocare vicini i dati pertinenti.

Casi limite

  • Aggregazioni DISTINCT:le query con aggregazioni DISTINCT possono essere costose dal punto di vista computazionale, soprattutto su set di dati di grandi dimensioni. Prendi in considerazione alternative come APPROX_COUNT_DISTINCT per risultati approssimativi.
  • Numero elevato di gruppi:se la query genera un numero elevato di gruppi, potrebbe consumare una quantità significativa di memoria. In questi casi, valuta la possibilità di limitare il numero di gruppi o di utilizzare una strategia di aggregazione diversa.

REPARTITION passaggio

REPARTITION e COALESCE sono tecniche di ottimizzazione che BigQuery applica direttamente ai dati rimescolati nella query.

  • REPARTITION: questa operazione mira a ribilanciare la distribuzione dei dati tra i nodi di lavoro. Supponiamo che, dopo il rimescolamento, un nodo worker finisca per avere una quantità di dati sproporzionatamente grande. Il passaggio REPARTITION ridistribuisce i dati in modo più uniforme, impedendo a un singolo worker di diventare un collo di bottiglia. Ciò è particolarmente importante per le operazioni a elevato consumo di risorse di calcolo come i join.
  • COALESCE: questo passaggio si verifica quando hai molti piccoli bucket di dati dopo il rimescolamento. Il passaggio COALESCE combina questi bucket in bucket più grandi, riducendo l'overhead associato alla gestione di numerosi piccoli pezzi di dati. Ciò può essere particolarmente utile quando si ha a che fare con set di risultati intermedi molto piccoli.

Se nel piano di esecuzione della query vengono visualizzati i passaggi REPARTITION o COALESCE, non significa necessariamente che ci sia un problema con la query. Spesso è un segnale che BigQuery sta ottimizzando in modo proattivo la distribuzione dei dati per migliorare le prestazioni. Tuttavia, se visualizzi queste operazioni ripetutamente, potrebbe indicare che i tuoi dati sono intrinsecamente distorti o che la tua query sta causando un rimescolamento eccessivo dei dati.

Ottimizza

Per ridurre il numero di passaggi di REPARTITION, prova a:

  • Distribuzione dei dati:assicurati che le tabelle siano partizionate e raggruppate in modo efficace. I dati ben distribuiti riducono la probabilità di squilibri significativi dopo il rimescolamento.
  • Struttura della query:analizza la query per individuare potenziali fonti di distorsione dei dati. Ad esempio, esistono filtri o join altamente selettivi che comportano l'elaborazione di un piccolo sottoinsieme di dati su un singolo worker?
  • Strategie di unione:prova diverse strategie di unione per vedere se portano a una distribuzione dei dati più equilibrata.

Per ridurre il numero di passaggi di COALESCE, prova a:

  • Strategie di aggregazione: valuta la possibilità di eseguire le aggregazioni prima nella pipeline di query. Ciò può contribuire a ridurre il numero di piccoli set di risultati intermedi che potrebbero causare passaggi COALESCE.
  • Volume di dati:se hai a che fare con set di dati molto piccoli, COALESCE potrebbe non essere un problema significativo.

Non ottimizzare eccessivamente. L'ottimizzazione prematura potrebbe rendere le query più complesse senza produrre vantaggi significativi.

Spiegazione delle query federate

Le query federate ti consentono di inviare un'istruzione di query a un'origine dati esterna utilizzando la funzione EXTERNAL_QUERY. Le query federate sono soggette alla tecnica di ottimizzazione nota come pushdown SQL e il piano di query mostra le operazioni eseguite nell'origine dati esterna, se presente. Ad esempio, se esegui la query seguente:

SELECT id, name
FROM EXTERNAL_QUERY("<connection>", "SELECT * FROM company")
WHERE country_code IN ('ee', 'hu') AND name like '%TV%'

Il piano di query mostrerà i seguenti passaggi della fase:

$1:id, $2:name, $3:country_code
FROM table_for_external_query_$_0(
  SELECT id, name, country_code
  FROM (
    /*native_query*/
    SELECT * FROM company
  )
  WHERE in(country_code, 'ee', 'hu')
)
WHERE and(in($3, 'ee', 'hu'), like($2, '%TV%'))
$1, $2
TO __stage00_output

In questo piano, table_for_external_query_$_0(...) rappresenta la funzione EXTERNAL_QUERY. Tra parentesi puoi vedere la query eseguita dall'origine dati esterna. In base a questo, puoi notare che:

  • Un'origine dati esterna restituisce solo tre colonne selezionate.
  • Un'origine dati esterna restituisce solo le righe per le quali country_code è 'ee' o 'hu'.
  • L'operatore LIKE non viene eseguito il push e viene valutato da BigQuery.

A titolo di confronto, se non sono presenti pushdown, il piano di query mostrerà i seguenti passaggi della fase:

$1:id, $2:name, $3:country_code
FROM table_for_external_query_$_0(
  SELECT id, name, description, country_code, primary_address, secondary address
  FROM (
    /*native_query*/
    SELECT * FROM company
  )
)
WHERE and(in($3, 'ee', 'hu'), like($2, '%TV%'))
$1, $2
TO __stage00_output

Questa volta un'origine dati esterna restituisce tutte le colonne e tutte le righe della tabella company e BigQuery esegue il filtraggio.

Metadati Timeline

La cronologia delle query mostra i progressi in momenti specifici, fornendo istantanee dei progressi complessivi delle query. La cronologia è rappresentata come una serie di campioni che riportano i seguenti dettagli:

Campo Descrizione
elapsedMs Millisecondi trascorsi dall'inizio dell'esecuzione della query.
totalSlotMs Una rappresentazione cumulativa dei millisecondi di slot utilizzati dalla query.
pendingUnits Unità di lavoro totali pianificate e in attesa di esecuzione.
activeUnits Il numero totale di unità di lavoro attive in fase di elaborazione da parte dei worker.
completedUnits Il numero totale di unità di lavoro completate durante l'esecuzione di questa query.

Query di esempio

La seguente query conta il numero di righe nel set di dati pubblico di Shakespeare e ha un secondo conteggio condizionale che limita i risultati alle righe che fanno riferimento ad "Amleto":

SELECT
  COUNT(1) as rowcount,
  COUNTIF(corpus = 'hamlet') as rowcount_hamlet
FROM `publicdata.samples.shakespeare`

Fai clic su Dettagli esecuzione per visualizzare il piano di query:

Il piano di query di Hamlet.

Gli indicatori di colore mostrano le tempistiche relative per tutti i passaggi in tutte le fasi.

Per saperne di più sui passaggi delle fasi di esecuzione, fai clic su per espandere i dettagli della fase:

I dettagli del passaggio del piano di query hamlet.

In questo esempio, il tempo più lungo in qualsiasi segmento è stato il tempo trascorso dal singolo worker nella fase 01 in attesa del completamento della fase 00. Questo perché la fase 01 dipendeva dall'input della fase 00 e non poteva iniziare finché la prima fase non scriveva il suo output nel rimescolamento intermedio.

Segnalazione degli errori

È possibile che i job di query non vengano eseguiti correttamente. Poiché le informazioni sul piano vengono aggiornate periodicamente, puoi osservare in quale punto del grafico di esecuzione si è verificato l'errore. Nella console Cloud de Confiance , le fasi riuscite o non riuscite sono contrassegnate da un segno di spunta o un punto esclamativo accanto al nome della fase.

Per ulteriori informazioni sull'interpretazione e la risoluzione degli errori, consulta la guida alla risoluzione dei problemi.

Rappresentazione di esempio dell'API

Le informazioni sul piano di query sono incorporate nelle informazioni di risposta del job e puoi recuperarle chiamando jobs.get. Ad esempio, il seguente estratto di una risposta JSON per un job che restituisce la query di esempio hamlet mostra sia il piano di query sia le informazioni sulla cronologia.

"statistics": {
  "creationTime": "1576544129234",
  "startTime": "1576544129348",
  "endTime": "1576544129681",
  "totalBytesProcessed": "2464625",
  "query": {
    "queryPlan": [
      {
        "name": "S00: Input",
        "id": "0",
        "startMs": "1576544129436",
        "endMs": "1576544129465",
        "waitRatioAvg": 0.04,
        "waitMsAvg": "1",
        "waitRatioMax": 0.04,
        "waitMsMax": "1",
        "readRatioAvg": 0.32,
        "readMsAvg": "8",
        "readRatioMax": 0.32,
        "readMsMax": "8",
        "computeRatioAvg": 1,
        "computeMsAvg": "25",
        "computeRatioMax": 1,
        "computeMsMax": "25",
        "writeRatioAvg": 0.08,
        "writeMsAvg": "2",
        "writeRatioMax": 0.08,
        "writeMsMax": "2",
        "shuffleOutputBytes": "18",
        "shuffleOutputBytesSpilled": "0",
        "recordsRead": "164656",
        "recordsWritten": "1",
        "parallelInputs": "1",
        "completedParallelInputs": "1",
        "status": "COMPLETE",
        "steps": [
          {
            "kind": "READ",
            "substeps": [
              "$1:corpus",
              "FROM publicdata.samples.shakespeare"
            ]
          },
          {
            "kind": "AGGREGATE",
            "substeps": [
              "$20 := COUNT($30)",
              "$21 := COUNTIF($31)"
            ]
          },
          {
            "kind": "COMPUTE",
            "substeps": [
              "$30 := 1",
              "$31 := equal($1, 'hamlet')"
            ]
          },
          {
            "kind": "WRITE",
            "substeps": [
              "$20, $21",
              "TO __stage00_output"
            ]
          }
        ]
      },
      {
        "name": "S01: Output",
        "id": "1",
        "startMs": "1576544129465",
        "endMs": "1576544129480",
        "inputStages": [
          "0"
        ],
        "waitRatioAvg": 0.44,
        "waitMsAvg": "11",
        "waitRatioMax": 0.44,
        "waitMsMax": "11",
        "readRatioAvg": 0,
        "readMsAvg": "0",
        "readRatioMax": 0,
        "readMsMax": "0",
        "computeRatioAvg": 0.2,
        "computeMsAvg": "5",
        "computeRatioMax": 0.2,
        "computeMsMax": "5",
        "writeRatioAvg": 0.16,
        "writeMsAvg": "4",
        "writeRatioMax": 0.16,
        "writeMsMax": "4",
        "shuffleOutputBytes": "17",
        "shuffleOutputBytesSpilled": "0",
        "recordsRead": "1",
        "recordsWritten": "1",
        "parallelInputs": "1",
        "completedParallelInputs": "1",
        "status": "COMPLETE",
        "steps": [
          {
            "kind": "READ",
            "substeps": [
              "$20, $21",
              "FROM __stage00_output"
            ]
          },
          {
            "kind": "AGGREGATE",
            "substeps": [
              "$10 := SUM_OF_COUNTS($20)",
              "$11 := SUM_OF_COUNTS($21)"
            ]
          },
          {
            "kind": "WRITE",
            "substeps": [
              "$10, $11",
              "TO __stage01_output"
            ]
          }
        ]
      }
    ],
    "estimatedBytesProcessed": "2464625",
    "timeline": [
      {
        "elapsedMs": "304",
        "totalSlotMs": "50",
        "pendingUnits": "0",
        "completedUnits": "2"
      }
    ],
    "totalPartitionsProcessed": "0",
    "totalBytesProcessed": "2464625",
    "totalBytesBilled": "10485760",
    "billingTier": 1,
    "totalSlotMs": "50",
    "cacheHit": false,
    "referencedTables": [
      {
        "projectId": "publicdata",
        "datasetId": "samples",
        "tableId": "shakespeare"
      }
    ],
    "statementType": "SELECT"
  },
  "totalSlotMs": "50"
},

Utilizzo delle informazioni sull'esecuzione

I piani di query BigQuery forniscono informazioni su come il servizio esegue le query, ma la natura gestita del servizio limita l'azione diretta su alcuni dettagli. Molte ottimizzazioni vengono eseguite automaticamente utilizzando il servizio, il che può differire da altri ambienti in cui la messa a punto, il provisioning e il monitoraggio possono richiedere personale dedicato e competente.

Per tecniche specifiche che possono migliorare l'esecuzione e il rendimento delle query, consulta la documentazione sulle best practice. Le statistiche del piano e della cronologia delle query possono aiutarti a capire se determinate fasi dominano l'utilizzo delle risorse. Ad esempio, una fase JOIN che genera molte più righe di output rispetto alle righe di input può indicare l'opportunità di filtrare in precedenza nella query.

Inoltre, le informazioni sulla cronologia possono aiutare a determinare se una determinata query è lenta in isolamento o a causa degli effetti di altre query che competono per le stesse risorse. Se noti che il numero di unità attive rimane limitato per tutta la durata della query, ma la quantità di unità di lavoro in coda rimane elevata, ciò può rappresentare casi in cui la riduzione del numero di query simultanee può migliorare significativamente il tempo di esecuzione complessivo per determinate query.