All'interno dei job di query, BigQuery include informazioni di diagnostica sul piano di query e sui tempi. È simile alle informazioni fornite da istruzioni come EXPLAIN
in altri sistemi di database e analisi. Queste informazioni possono essere recuperate dalle risposte dell'API di metodi come jobs.get
.
Per le query che richiedono molto tempo, BigQuery aggiorna periodicamente queste statistiche. Questi aggiornamenti vengono eseguiti indipendentemente dalla frequenza con cui viene eseguito il polling dello stato del job, ma in genere non si verificano più di una volta ogni 30 secondi. Inoltre, i job di query che non utilizzano risorse di esecuzione, come richieste di prova secca o risultati che possono essere pubblicati dai risultati memorizzati nella cache, non includeranno le informazioni di diagnostica aggiuntive, anche se potrebbero essere presenti altre statistiche.
Contesto
Quando BigQuery esegue un job di query, converte l'istruzione SQL dichiarativa in un grafo di esecuzione, suddiviso in una serie di fasi di query, che a loro volta sono composte da insiemi più granulari di passaggi di esecuzione. BigQuery sfrutta un'architettura parallela fortemente distribuita per eseguire queste query. Le fasi modellano le unità di lavoro che molti potenziali lavoratori possono eseguire in parallelo. Le fasi comunicano tra loro utilizzando un'architettura di ordinamento distribuita rapida.
All'interno del piano di query, i termini unità di lavoro e worker vengono utilizzati per trasmettere informazioni specifiche sul parallelismo. In altre parti di
BigQuery, potresti trovare il termine slot, che è una representatione astratta di più aspetti dell'esecuzione delle query, tra cui risorse di calcolo, memoria e I/O. Le statistiche dei job di primo livello forniscono la stima del costo di singole query utilizzando la stima totalSlotMs
della query con questo sistema di contabilità astratto.
Un'altra proprietà importante dell'architettura di esecuzione delle query è che è dinamica, il che significa che il piano di query può essere modificato durante l'esecuzione di una query. Le fasi introdotte durante l'esecuzione di una query vengono spesso utilizzate per migliorare la distribuzione dei dati tra i worker di query. Nei piani di query in cui si verifica questo problema, queste fasi sono in genere etichettate come fasi di ripartizione.
Oltre al piano di query, i job di query mostrano anche una sequenza temporale di esecuzione, che fornisce un conteggio delle unità di lavoro completate, in attesa e attive nei worker di query. Una query può avere più fasi contemporaneamente con worker attivi e la sequenza temporale è progettata per mostrare l'avanzamento complessivo della query.
Visualizzazione delle informazioni con la console Google Cloud
Nella console Google Cloud, puoi visualizzare i dettagli del piano di query per una query completata facendo clic sul pulsante Dettagli esecuzione (vicino al pulsante Risultati).
Informazioni sul piano di query
Nella risposta dell'API, i piani di query sono rappresentati come un elenco di fasi di query. Ogni elemento dell'elenco mostra statistiche di panoramica per fase, informazioni dettagliate sui passaggi e classificazioni dei tempi di ciascuna fase. Non tutti i dettagli vengono visualizzati nella console Google Cloud, ma possono essere tutti presenti nelle risposte dell'API.
Panoramica della fase
I campi di panoramica per ogni fase possono includere quanto segue:
Campo API | Descrizione |
---|---|
id |
ID numerico univoco per la fase. |
name |
Nome di riepilogo semplice per la fase. I steps all'interno della fase forniscono 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 di 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 epoch che rappresenta il momento in cui il primo worker all'interno della fase ha iniziato l'esecuzione. |
endMs |
Timestamp in millisecondi epoch che rappresenta il momento in cui l'ultimo worker ha completato l'esecuzione. |
steps |
Elenco più dettagliato dei passaggi di esecuzione all'interno della fase. Per ulteriori informazioni, consulta la sezione successiva. |
recordsRead |
Dimensioni di input della fase come numero di record in tutti i worker della fase. |
recordsWritten |
Dimensione dell'output della fase come numero di record in tutti i worker della fase. |
parallelInputs |
Numero di unità di lavoro parallelizzabili per la fase. A seconda della fase e della query, può rappresentare il numero di segmenti colonnari all'interno di una tabella o il numero di partizioni all'interno di un'operazione di mescolamento intermedio. |
completedParallelInputs |
Numero di unità di lavoro completate nella fase. Per alcune query, non è necessario compilare tutti gli input all'interno di una fase per il completamento della fase. |
shuffleOutputBytes |
Rappresenta i byte totali scritti su tutti i worker all'interno di una fase di query. |
shuffleOutputBytesSpilled |
Le query che trasmettono dati significativi tra le fasi potrebbero dover ricorrere alla trasmissione basata su disco. La statistica dei byte con overflow indica la quantità di dati che sono stati trasferiti sul disco. Dipende da un algoritmo di ottimizzazione, pertanto non è deterministico per una determinata query. |
Classificazione dei tempi per fase
Le fasi di query forniscono classificazioni dei tempi delle fasi, sia in forma relativa che assoluta. Poiché ogni fase di esecuzione rappresenta il lavoro intrapreso da uno o più lavoratori indipendenti, le informazioni vengono fornite sia in termini di tempo medio che di tempo peggiore. Questi tempi rappresentano il rendimento medio di tutti i worker in una fase, nonché il rendimento del worker più lento della coda lunga per una determinata classificazione. Inoltre, i tempi medi e massimi sono suddivisi in rappresentazioni absolute e relative. Per le statistiche basate su rapporti, i dati vengono forniti come frazione del tempo più lungo trascorso da qualsiasi worker in qualsiasi segmento.
La console Google Cloud presenta la tempistica delle fasi utilizzando le rappresentazioni della tempistica relativa.
Le informazioni sui tempi della fase vengono riportate come segue:
Tempi relativi | Temporizzazione assoluta | Numeratore del rapporto |
---|---|---|
waitRatioAvg |
waitMsAvg |
Tempo medio impiegato dal worker in attesa di essere pianificato. |
waitRatioMax |
waitMsMax |
Tempo impiegato dal worker più lento in attesa di essere pianificato. |
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 impiegato dal worker medio per la CPU. |
computeRatioMax |
computeMsMax |
Tempo impiegato dal worker più lento per il vincolo della CPU. |
writeRatioAvg |
writeMsAvg |
Tempo impiegato dal lavoratore 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 ciascun worker all'interno di una fase, presentate come un elenco ordinato di operazioni. Ogni operazione del passaggio ha una categoria, con alcune operazioni che forniscono informazioni più dettagliate. Le categorie di operazioni presenti nel piano di query includono quanto segue:
Categoria 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 |
Un'operazione ORDER BY che include le chiavi di colonna e l'ordinamento. |
AGGREGATE |
Implementa aggregazioni per clausole come GROUP BY o COUNT , tra le altre. |
LIMIT |
Implementa la clausola LIMIT . |
JOIN |
Implementa join per clausole come JOIN , tra le altre; include il tipo di join e, eventualmente, le condizioni di join. |
ANALYTIC_FUNCTION |
Un'invocazione di una funzione finestra (detta anche "funzione analitica"). |
USER_DEFINED_FUNCTION |
Un'invocazione a una funzione definita dall'utente. |
Interpreta e ottimizza 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 per l'ordinamento casuale. Quando vengono letti i dati di una fase precedente, BigQuery legge i dati dalla memoria di smistamento. La quantità di dati analizzati influisce sui costi
quando si utilizzano gli slot on demand e sulle prestazioni quando si utilizzano le prenotazioni.
Potenziali problemi di rendimento
- Scansione di grandi tabelle non partizionate: se la query richiede solo una piccola parte dei dati, potrebbe indicare che una scansione della tabella non è efficiente. Il partizionamento potrebbe essere una buona strategia di ottimizzazione.
- Scansione di una tabella di grandi dimensioni con un rapporto di filtro ridotto:questo suggerisce che il filtro non riduce in modo efficace i dati sottoposti a scansione. Valuta la possibilità di rivedere le condizioni di filtro.
- Byte di smistamento trasferiti sul disco: questo indica che i dati non vengono archiviati in modo efficace utilizzando tecniche di ottimizzazione come il clustering, che potrebbero mantenere dati simili in cluster.
Ottimizza
- Filtro mirato:utilizza le clausole
WHERE
in modo strategico per filtrare i dati irrilevanti il prima possibile nella query. In questo modo, viene ridotta la quantità di dati da elaborare dalla query. - Creazione di partizioni e cluster:BigQuery utilizza la suddivisione in partizioni e il clustering delle tabelle per individuare in modo efficiente segmenti di dati specifici.
Assicurati che le tabelle siano partizionate e raggruppate in base ai tuoi 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 utilizzaSELECT * EXCEPT
per evitare di leggere dati non necessari. - Viste materializzate:le viste materializzate possono precompilare e memorizzare le 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 in
SELECT
,WHERE
,HAVING
e altre clausole 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 nella 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.
- Correla il passaggio
COMPUTE
con il volume di dati: se una fase mostra un calcolo significativo ed elabora un volume elevato di dati, potrebbe essere una buona candidata per l'ottimizzazione. - Dati distorti: per le fasi in cui il valore massimo di calcolo è notevolmente superiore alla media di calcolo, questo indica che la fase ha impiegato un tempo sproporzionato per elaborare alcuni intervalli di dati. Valuta la possibilità di esaminare la distribuzione dei dati per verificare se è presente un disallineamento.
- Valuta i tipi di dati:utilizza tipi di dati appropriati per le colonne. Ad esempio, l'utilizzo di numeri interi, date e timestamp anziché di stringhe può migliorare le prestazioni.
WRITE
passaggio
I passaggi WRITE
vengono eseguiti per i dati intermedi e l'output finale.
- Scrittura nella memoria per l'ordinamento casuale: in una query a più fasi, il passaggio
WRITE
spesso prevede l'invio dei dati elaborati a un'altra fase per un'ulteriore elaborazione. Questo è tipico della memoria per l'ordinamento casuale, che combina o aggrega i dati provenienti da più origini. I dati scritti durante questa fase sono tipicamente 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 i dati in un'uscita partizionata con hash, BigQuery scrive le colonne incluse nell'output e la colonna scelta come chiave di partizione.
Ottimizza
Anche se il passaggio WRITE
stesso potrebbe non essere ottimizzato direttamente, comprendere il suo ruolo può aiutarti a identificare potenziali colli di bottiglia nelle fasi precedenti:
- Riduci al minimo i dati scritti:concentrati sull'ottimizzazione delle fasi precedenti con filtrazione e aggregazione per ridurre la quantità di dati scritti durante questo passaggio.
Partizionamento:la scrittura trae grandi vantaggi dal partitioning delle tabelle. Se i dati che scrivi sono limitati a partizioni specifiche, BigQuery può eseguire scritture più velocemente.
Se l'istruzione DML contiene una clausola
WHERE
con una condizione statica in base a una colonna della partizione della tabella, BigQuery modifica solo le partizioni della tabella pertinenti.Svantaggi della denormalizzazione: a volte la denormalizzazione può portare a insiemi di risultati più piccoli nel passaggio intermedio
WRITE
. Tuttavia, presenta degli svantaggi, come l'aumento dell'utilizzo dello spazio di archiviazione e le difficoltà di consistenza dei dati.
JOIN
passaggio
Nel passaggio JOIN
, BigQuery combina i dati di due
origini dati. Le unioni possono includere condizioni di join. I join richiedono molte risorse. Quando si uniscono dati di grandi dimensioni in BigQuery, le chiavi di join vengono mescolate in modo indipendente per allinearsi nello 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:
- Modello 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 join:sono le colonne utilizzate per abbinare le righe tra le diverse origini dati. La scelta delle colonne è fondamentale per il rendimento dell'unione.
Pattern di join
- Unione dinamica:quando una tabella, in genere quella più piccola, può essere inserita in memoria su un singolo slot o nodo worker, BigQuery può trasmetterla a tutti gli altri nodi per eseguire l'unione in modo efficiente. Cerca
JOIN EACH WITH ALL
nei dettagli del passaggio. - Unione con hash:quando le tabelle sono di grandi dimensioni o un'unione broadcast non è appropriata, è possibile utilizzare un'unione con hash. BigQuery utilizza operazioni di hashing e smistamento per mescolare le tabelle sinistra e destra in modo che le chiavi corrispondenti finiscano nello stesso slot per eseguire un join locale. I join di 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 antipattern SQL in cui una tabella viene unita a se stessa.
- Join croce:un antipattern SQL che può causare problemi di prestazioni significativi perché genera dati di output più grandi degli input.
- Unione distorta: la distribuzione dei dati tra la chiave di join in una tabella è molto distorta e può causare problemi di prestazioni. Cerca i casi in cui il tempo di calcolo massimo è molto superiore al tempo di calcolo medio nel piano di query. Per ulteriori informazioni, consulta la sezione Unione con elevata cardinalità e Spostamento della partizione.
Debug
- Volume di dati elevato: 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 applicare filtri o di utilizzare chiavi di join più selettive. - Distribuzione non uniforme dei dati:analizza la distribuzione dei dati delle chiavi di join. Se una tabella è molto distorta, valuta strategie come la suddivisione della query o il prefiltro.
- Join con cardinalità elevata:i join che producono molte più righe rispetto al numero di righe di input sinistro e destro 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
oLEFT
, 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
se possibile. I confrontiSTRING
sono più lenti dei confrontiINT64
perché confrontano ogni carattere di una stringa. I numeri interi richiedono un solo confronto. - Filtro prima dell'unione:applica i filtri delle clausole
WHERE
alle singole tabelle prima dell'unione. In questo modo, viene ridotta la quantità di dati coinvolti nell'operazione di join. - Evita le funzioni nelle colonne di join:evita di chiamare funzioni nelle colonne di join. Standardizza invece i dati delle tabelle durante il processo di importazione o post-importazione utilizzando le pipeline SQL ELT. Questo approccio elimina la necessità di modificare dinamicamente le colonne di join, il che consente join più efficienti senza compromettere l'integrità dei dati.
- Evita i self join: i self join vengono utilizzati comunemente per calcolare le relazioni dipendenti dalle righe. Tuttavia, i join autoreferenziali possono potenzialmente quadruplicare il numero di righe di output, causando problemi di prestazioni. Anziché fare affidamento su self-join, ti consigliamo di utilizzare le funzioni finestra (analitiche).
- Prima le tabelle di grandi dimensioni: anche se l'ottimizzatore delle query SQL può determinare quale tabella deve trovarsi su quale lato del join, ordina le tabelle unite in modo appropriato. La best practice è posizionare prima la tabella più grande, seguita dalla più piccola e poi dalle altre in ordine decrescente di dimensioni.
- Denormalizzazione:in alcuni casi, la denormalizzazione strategica delle tabelle (aggiungendo dati ridondanti) può eliminare del tutto le unioni. 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 colocalizzati possono velocizzare notevolmente le unioni consentendo a BigQuery di avere come target le partizioni di dati pertinenti.
- Ottimizzazione dei join distorti: per evitare problemi di prestazioni associati ai join distorti, 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 della fase: controlla il numero di righe di input e di output dell'aggregazione e le dimensioni dello smistamento per determinare la quantità di riduzione dei dati ottenuta dal passaggio di aggregazione e se è stato utilizzato lo smistamento dei dati.
- Dimensione dell'ordinamento casuale:una dimensione dell'ordinamento casuale elevata potrebbe indicare che una quantità significativa di dati è stata spostata tra i nodi worker durante l'aggregazione.
- Verifica la distribuzione dei dati: assicurati che i dati siano distribuiti uniformemente tra le partizioni. La distribuzione non uniforme dei dati può portare a carichi di lavoro sbilanciati nel passaggio di aggregazione.
- Esamina le aggregazioni:analizza le clausole di aggregazione per confermare che siano necessarie ed efficienti.
Ottimizza
- Clustering:raggruppa le tabelle in base alle colonne utilizzate di frequente in
GROUP BY
,COUNT
o altre clausole di aggregazione. - Partizione:scegli una strategia di partizione 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 sottoposti a scansione durante l'aggregazione.
- Esegui l'aggregazione prima:se possibile, esegui le aggregazioni prima nella pipeline di query. In questo modo, puoi ridurre la quantità di dati da elaborare durante l'aggregazione.
- Ottimizzazione del rimescolamento:se il rimescolamento rappresenta un collo di bottiglia, scopri i modi per ridurlo al minimo. Ad esempio, denormalizza le tabelle o utilizza il clustering per collocare insieme i dati pertinenti.
Casi limite
- Aggregati DISTINCT: le query con aggregati
DISTINCT
possono essere molto dispendiose in termini di risorse di calcolo, soprattutto su set di dati di grandi dimensioni. Valuta alternative comeAPPROX_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
Sia REPARTITION
che COALESCE
sono tecniche di ottimizzazione che BigQuery applica direttamente ai dati rimescolati nella query.
REPARTITION
: questa operazione mira a riequilibrare la distribuzione dei dati tra i nodi di lavoro. Supponiamo che dopo il rimescolamento, un nodo worker finisca con una quantità di dati sproporzionatamente grande. Il passaggioREPARTITION
ridistribuisce i dati in modo più uniforme, impedendo a un singolo worker di diventare un collo di bottiglia. Questo è particolarmente importante per operazioni con un'elevata intensità di calcolo come le unioni.COALESCE
: questo passaggio si verifica quando hai molti piccoli bucket di dati dopo il rimescolamento. Il passaggioCOALESCE
combina questi bucket in altri più grandi, riducendo l'overhead associato alla gestione di numerosi piccoli pezzi di dati. Questo può essere particolarmente utile quando si tratta di set di risultati intermedi molto piccoli.
Se nel piano di query vengono visualizzati i passaggi REPARTITION
o COALESCE
, non necessariamente significa che esiste un problema con la query. Spesso è un segno che
BigQuery sta ottimizzando in modo proattivo la distribuzione dei dati per migliorare
le prestazioni. Tuttavia, se noti queste operazioni ripetutamente, potrebbe indicare che i tuoi dati sono intrinsecamente distorti o che la tua query sta causando un eccessivo rimescolamento dei dati.
Ottimizza
Per ridurre il numero di passaggi REPARTITION
, prova a procedere nel seguente modo:
- Distribuzione dei dati: assicurati che le tabelle siano partizionate e messe in cluster 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 scostamento dei dati. Ad esempio, sono presenti filtri o join altamente selettivi che comportano l'elaborazione di un piccolo sottoinsieme di dati su un singolo worker?
- Strategie di join: fai esperimenti con diverse strategie di join per vedere se generano una distribuzione dei dati più equilibrata.
Per ridurre il numero di passaggi COALESCE
, prova a procedere nel seguente modo:
- Strategie di aggregazione:valuta la possibilità di eseguire aggregazioni nelle prime fasi della pipeline di query. In questo modo puoi ridurre il numero di piccoli set di risultati intermedi che potrebbero causare i passaggi
COALESCE
. - Volume di dati: se hai a che fare con set di dati molto piccoli,
COALESCE
potrebbe non essere un problema significativo.
Non eseguire un'ottimizzazione eccessiva. L'ottimizzazione prematura potrebbe rendere le query più complesse senza apportare 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 spostate all'origine dati esterna, se presenti.
Ad esempio, se esegui la seguente query:
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 ciò, 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 sottoposto a push down e viene valutato da BigQuery.
Per fare un 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 filtro.
Metadati di Spostamenti
La cronologia delle query registra i progressi in momenti specifici, fornendo visualizzazioni istantanee dell'avanzamento complessivo 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 dello slot utilizzati dalla query. |
pendingUnits |
Unità di lavoro totali pianificate e in attesa di esecuzione. |
activeUnits |
Unità di lavoro attive totali in fase di elaborazione dai worker. |
completedUnits |
Unità di lavoro totali completate durante l'esecuzione di questa query. |
Un esempio di query
La seguente query conteggia 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 a "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:
Gli indicatori di colore mostrano i tempi relativi di tutti i passaggi in tutte le fasi.
Per scoprire di più sui passaggi delle fasi di esecuzione, fai clic su
per espandere i dettagli della fase:In questo esempio, il tempo più lungo in qualsiasi segmento è stato il tempo impiegato dal singolo worker nella fase 01 per attendere il completamento della fase 00. Questo perché la fase 01 dipendeva dall'input della fase 00 e non poteva iniziare fino a quando la prima fase non scriveva l'output nell'ordinamento intermedio.
Segnalazione degli errori
È possibile che i job di query non vadano a buon fine durante l'esecuzione. Poiché le informazioni sul piano vengono aggiornate periodicamente, puoi osservare dove si è verificato l'errore nel grafico di esecuzione. Nella console Google Cloud, le fasi riuscite o non riuscite sono contrassegnate da un segno di spunta o da un punto esclamativo accanto al nome della fase.
Per ulteriori informazioni sull'interpretazione e sulla correzione degli errori, consulta la guida alla risoluzione dei problemi.
Rappresentazione di un esempio di API
Le informazioni sul piano di query sono incorporate nelle informazioni sulla risposta al job e puoi recuperarle chiamando jobs.get
. Ad esempio,
il seguente estratto di una risposta JSON per un job
che restituisce la query Hamlet di esempio mostra sia il piano di query sia le informazioni sulle tempistiche.
"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 di BigQuery forniscono informazioni su come il servizio esegue le query, ma la natura gestita del servizio limita la possibilità di applicare direttamente alcuni dettagli. Molte ottimizzazioni vengono eseguite automaticamente utilizzando il servizio, che può essere diverso da altri ambienti in cui la regolazione, il provisioning e il monitoraggio possono richiedere personale dedicato e competente.
Per tecniche specifiche che possono migliorare l'esecuzione e le prestazioni delle query, consulta la documentazione sulle best practice. Le statistiche del piano di query e della cronologia possono aiutarti a capire se determinate fasi predominano nell'utilizzo delle risorse. Ad esempio, una fase JOIN che genera molto più righe di output rispetto alle righe di input può indicare un'opportunità di applicare un filtro all'inizio della query.
Inoltre, le informazioni sulle tempistiche possono aiutarti a identificare se una determinata query è lenta in modo isolato o a causa degli effetti di altre query in competizione 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, puoi trovarti in casi in cui la riduzione del numero di query simultanee può migliorare notevolmente il tempo di esecuzione complessivo per determinate query.