Incorporado a jobs de consulta, o BigQuery inclui informações de cronologia e plano de consulta diagnóstica. Isso é semelhante aos dados fornecidos por instruções como EXPLAIN
em outros sistemas analíticos e de bancos de dados. Essas informações podem ser recuperadas a partir das respostas de API de métodos como jobs.get
.
Para consultas de longa duração, o BigQuery atualizará essas estatísticas periodicamente. Essas atualizações ocorrem independentemente da taxa em que o status do job é pesquisado, mas não costumam acontecer com uma frequência maior do que a cada 30 segundos. Além disso, os jobs de consulta que não aproveitam recursos de execução, como resultados ou solicitações simuladas que podem ser exibidos a partir de resultados em cache, não incluirão as informações extras de diagnóstico, embora outras estatísticas possam estar presentes.
Contexto
Quando o BigQuery executa um job de consulta, ele converte a instrução SQL declarativa em um gráfico de execução, desmembrado em uma série de estágios de consulta que, por sua vez, são compostos por conjuntos mais granulares de etapas de execução. O BigQuery usa uma arquitetura paralela altamente distribuída para executar essas consultas. Os estágios modelam as unidades de trabalho que muitos workers em potencial podem executar paralelamente. Esses estágios se comunicam usando uma arquitetura embaralhada de distribuição rápida. Leia mais sobre isso em Execução de consultas na memória no BigQuery.
No plano de consulta, os termos unidades de trabalho e workers são usados para transmitir informações sobre o paralelismo, especificamente. Em outros locais no BigQuery, é possível encontrar o termo slot, que é uma representação abstrata de várias facetas da execução de consulta, incluindo recursos de computação, memória e E/S. As estatísticas de jobs de nível superior fornecem a estimativa de custo da consulta individual usando a estimativa totalSlotMs
da consulta que utiliza essa contabilidade abstrata.
Outra propriedade importante da arquitetura de execução de consulta é o fato de ela ser dinâmica, ou seja, o plano pode ser modificado enquanto uma consulta está em execução. Os estágios que são introduzidos durante a execução de uma consulta costumam ser usados para melhorar a distribuição de dados em todos os workers da consulta. Nos planos em que isso ocorre, eles normalmente são rotulados como estágios de repartição.
Além do plano de consulta, os jobs de consulta também exibem um cronograma de execução, que fornece uma contabilidade das unidades de trabalho concluídas, pendentes e ativas nos workers de consulta. Como uma consulta pode ter vários cenários com workers ativos simultaneamente, o cronograma se destina a mostrar o progresso geral dela.
Como visualizar informações com o Console do Cloud
No Console do Cloud, é possível ver os detalhes do plano de consulta de uma consulta concluída clicando no botão Detalhes da execução (perto do botão Resultados).
Informações do plano de consulta
Na resposta da API, os planos de consulta são representados como uma lista de estágios de consulta. Cada item na lista mostra estatísticas da visão geral por cenário, informações detalhadas da etapa e classificações de cronologia dos cenários. Nem todos os detalhes são renderizados no Console do Cloud, mas todos podem estar presentes nas respostas da API.
Visão geral do cenário
Os campos de visão geral de cada estágio podem incluir o seguinte:
Campo da API | Descrição |
---|---|
id |
Código numérico exclusivo do cenário. |
name |
Nome simples de resumo do cenário. O steps dentro do estágio fornece detalhes adicionais sobre as etapas de execução. |
status |
Status de execução do cenário. Os estados possíveis incluem PENDING, RUNNING, COMPLETE, FAILED e CANCELLED. |
inputStages |
Uma lista dos códigos que formam o gráfico de dependência do cenário. Por exemplo, um cenário JOIN geralmente precisa de dois cenários dependentes que preparam os dados nos lados esquerdo e direito do relacionamento JOIN. |
startMs |
Carimbo de data/hora, em milissegundos da época, que representa quando o primeiro trabalhador no cenário iniciou a execução. |
endMs |
Carimbo de data/hora, em milissegundos de época, que representa quando o último trabalhador concluiu a execução. |
steps |
Lista mais detalhada de etapas de execução no cenário. Consulte a próxima seção para mais informações. |
recordsRead |
Tamanho de entrada do cenário como número de registros, em todos os trabalhadores do cenário. |
recordsWritten |
Tamanho de saída do cenário como número de registros, em todos os trabalhadores do cenário. |
parallelInputs |
Número de unidades de trabalho carregáveis em paralelo do cenário. Dependendo do estágio e da consulta, isso pode representar o número de segmentos colunares em uma tabela ou o número de partições em um embaralhamento intermediário. |
completedParallelInputs |
Número de unidades de trabalho dentro do cenário que foram concluídas. Para algumas consultas, nem todas as entradas dentro de um cenário precisam ser concluídas para que o cenário seja concluído. |
shuffleOutputBytes |
Representa o total de bytes gravados em todos os trabalhadores em um cenário de consulta. |
shuffleOutputBytesSpilled |
Consultas que transmitem dados significativos entre cenários podem precisar recorrer à transmissão baseada em disco. A estatística de bytes espalhados comunica o volume de dados espalhados no disco. Depende de um algoritmo de otimização para que não seja determinístico para qualquer consulta. |
Informações da etapa por cenário
As etapas representam as operações mais granulares que cada trabalhador em um cenário precisa executar, apresentadas como uma lista ordenada de operações. As etapas são categorizadas, e algumas operações fornecem informações mais detalhadas. As categorias de operação presentes no plano de consulta incluem os seguintes itens:
Etapa | Descrição |
---|---|
READ | Uma leitura de uma ou mais colunas de uma tabela de entrada ou de um embaralhamento intermediário. |
WRITE | Uma gravação de uma ou mais colunas em uma tabela de saída ou em um resultado intermediário. Para saídas particionadas HASH de um cenário, isso também inclui as colunas usadas como a chave de partição. |
COMPUTE | Operações como avaliação de expressão e funções SQL. |
FILTER | Operador que implementa as cláusulas WHERE, OMIT IF e HAVING. |
SORT | Classifica ou ordena por operação. Inclui as chaves de coluna e a direção de classificação. |
AGGREGATE | Uma operação de agregação, como GROUP BY ou COUNT. |
LIMIT | Operador que implementa a cláusula LIMIT. |
JOIN | Uma operação JOIN, que inclui o tipo de junção e as colunas usadas. |
ANALYTIC_FUNCTION | Uma invocação de uma função analítica, também conhecida como "função janela". |
USER_DEFINED_FUNCTION | Uma chamada a uma função definida pelo usuário. |
Classificação de cronologia por cenário
Os estágios de consulta também fornecem classificações de duração dos estágios, tanto em termos absolutos quanto relativos. Como cada estágio de execução representa o trabalho realizado por um ou mais workers independentes, as informações são fornecidas no tempo médio e no pior cenário. Esses tempos representam o desempenho médio de todos os workers em um estágio, assim como o desempenho mais lento de cauda longa dos workers em uma determinada classificação. Além disso, os tempos médio e máximo são desmembrados nas representações absoluta e relativa. Para estatísticas com base em proporção, os dados são fornecidos como uma fração do maior tempo gasto por qualquer worker em qualquer segmento.
O Console do Cloud apresenta a cronologia dos cenários usando as representações de cronologia relativa.
As informações de cronologia de cenário são relatadas da seguinte maneira:
Cronologia relativa | Cronologia absoluta | Numerador de proporção |
---|---|---|
waitRatioAvg |
waitMsAvg |
Tempo que o trabalho médio passou aguardando ser programado. |
waitRatioMax |
waitMsMax |
Tempo que o trabalho mais lento passou aguardando ser programado. |
readRatioAvg |
readMsAvg |
Tempo que o trabalho médio passou lendo dados de entrada. |
readRatioMax |
readMsMax |
Tempo que o trabalho mais lento passou lendo dados de entrada. |
computeRatioAvg |
computeMsAvg |
Tempo que o worker médio passou ligado à CPU. |
computeRatioMax |
computeMsMax |
Tempo que o worker mais lento passou ligado à CPU. |
writeRatioAvg |
writeMsAvg |
Tempo que o trabalho médio passou gravando dados de saída. |
writeRatioMax |
writeMsMax |
Tempo que o worker mais lento passou gravando dados de saída. |
Metadados do cronograma
O cronograma da consulta informa a evolução em momentos específicos no tempo, fornecendo visualizações instantâneas do progresso geral da consulta. O cronograma é representado por uma série de amostras que informam os seguintes detalhes:
Campo | Descrição |
---|---|
elapsedMs |
Milissegundos decorridos desde o início da execução da consulta. |
totalSlotMs |
Uma representação cumulativa dos milissegundos de slot usados pela consulta. |
pendingUnits |
Total de unidades de trabalho programadas que aguardam execução. |
activeUnits |
Total de unidades de trabalho ativas atualmente sendo processadas por trabalhadores. |
completedUnits |
Total de unidades de trabalho que foram concluídas durante a execução dessa consulta. |
Um exemplo de consulta
A consulta a seguir conta o número de linhas no conjunto de dados público de Shakespeare e tem uma segunda contagem condicional que restringe os resultados às linhas que fazem referência ao termo "Hamlet":
#StandardSQL
SELECT
COUNT(1) as rowcount,
COUNTIF(corpus = 'hamlet') as rowcount_hamlet
FROM `publicdata.samples.shakespeare`
Neste exemplo, é usada uma tabela de amostra muito pequena com uma consulta simples. Portanto, há apenas duas unidades de trabalho no total. Todo o trabalho é concluído quase imediatamente.
Clique em Detalhes da execução para ver o plano de consulta:
Os indicadores de cor mostram os tempos relativos de todas as etapas em todos os estágios. Por exemplo, a etapa COMPUTA,O do Estágio 00 mostra uma barra cuja fração sombreada é 21/30, já que 30 ms é o tempo máximo gasto em uma única etapa de qualquer cenário. As informações da entrada paralela mostram que cada estágio exigia apenas um único worker. Portanto, não há variação entre o tempo médio e o mais lento.
Se quiser saber mais sobre as etapas dos estágios de execução, clique no triângulo para expandir os detalhes de cada um:
Nesse exemplo, o maior tempo em qualquer segmento foi aquele em que o único worker no Estágio 01 passou aguardando a conclusão do Estágio 00. Isso ocorre porque o Estágio 01 era dependente da entrada do Estágio 00 e não podia ser iniciado até que o primeiro gravasse a respectiva saída (1 linha, ~18 bytes) no embaralhamento intermediário.
O plano de execução para o único worker que concluiu o trabalho relativo ao Estágio 00 mostra que, primeiro, os dados foram lidos (READ) na coluna de corpus da tabela de Shakespeare indicada. Em seguida, agregações (AGGREGATIONS) foram estabelecidas para as projeções COUNT
e COUNTIF
. A verificação dos dados exigiu a etapa computação (COMPUTE), que forneceu dados para as contagens normal e condicional. A saída foi gravada na saída embaralhada intermediária, rotulada como __stage00_output
neste plano.
Error Reporting
É possível que os jobs de consulta falhem no meio da execução. Como as informações do plano são atualizadas periodicamente, é possível observar, no gráfico de execução, onde ocorreu a falha. No Console do Cloud, os estágios bem-sucedidos ou com falha têm uma marca de seleção ou um ponto de exclamação ao lado do nome.
Para mais informações sobre como interpretar e corrigir erros, consulte o Guia de solução de problemas.
Representação de amostra de API
As informações do plano de consulta são incorporadas nos dados de resposta do job. Para recuperá-las, chame jobs.get
. Por exemplo, o trecho a seguir de uma resposta JSON de um job que retorna a consulta de amostra de Hamlet mostra o plano de consulta e as informações do cronograma.
"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" },
Como usar informações de execução
Os planos de consulta do BigQuery fornecem informações sobre como o serviço executa consultas, mas a natureza gerenciada do serviço limita a possibilidade de alguns detalhes serem diretamente acionáveis. Muitas otimizações ocorrem automaticamente com o uso do serviço, que pode ser diferente de outros ambientes em que o ajuste, provisionamento e monitoramento exigem uma equipe dedicada e capacitada.
Para técnicas específicas capazes de melhorar a execução e o desempenho de consultas, confira a documentação de práticas recomendadas. As estatísticas do plano de consulta e do cronograma podem ajudar você a entender se determinados estágios dominam a utilização de recursos. Por exemplo, um estágio JOIN que gera muito mais linhas de saída do que de entrada pode indicar uma oportunidade para fazer a filtragem mais cedo na consulta.
Além disso, as informações de cronograma podem ajudar a identificar se determinada consulta é lenta isoladamente ou devido aos efeitos de outras consultas que disputam os mesmos recursos. Se o número de unidades ativas permanece limitado durante todo o ciclo de vida da consulta, mas a quantidade de unidades de trabalho consultadas permanece alta, isso pode indicar que, nesses casos, reduzir o número de consultas simultâneas melhora significativamente o tempo de execução geral de determinadas consultas.