Plano de consulta e cronograma

Incorporado a jobs de consulta, o BigQuery inclui informações de cronologia e plano de consulta diagnóstica. Isso é semelhante às informações fornecidas por declarações como EXPLAIN em outros sistemas analíticos e de bancos de dados. Essas informações podem ser recuperadas 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 ser com mais frequência 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 disponibilizados a partir de resultados em cache, não incluirão as informações adicionais 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 cenários de consulta que, por sua vez, são compostos por conjuntos mais granulares de etapas de execução. O BigQuery aproveita uma arquitetura paralela altamente distribuída para executar essas consultas os cenários modelam as unidades de trabalho que muitos trabalhadores em potencial podem executar em paralelo. Os cenários comunicam-se entre si por meio de uma arquitetura rápida de embaralhamento distribuída, que foi discutida mais detalhadamente em outro lugar.

Dentro do plano de consulta, são usados os termos "unidades de trabalho" e "trabalhadores", já que o plano está transmitindo informações especificamente sobre paralelismo. Em outros lugares no BigQuery, você pode 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 do job de nível superior fornecem a estimativa do custo da consulta individual usando a estimativa totalSlotMs da consulta que usa essa contabilidade abstrata.

Outra propriedade importante da arquitetura de execução de consulta é que ela é dinâmica, o que significa que o plano de consulta pode ser modificado enquanto uma consulta está em andamento. Cenários que são introduzidos durante a execução de uma consulta são frequentemente usados para melhorar a distribuição de dados em todos os trabalhadores de consulta. Nos planos de consulta em que isso ocorre, eles costumam são marcados como cenários de repartição.

Além do plano de consulta, os jobs de consulta também expõem um cronograma de execução, que fornece uma contabilidade das unidades de trabalho concluídas, pendentes e ativas nos trabalhadores de consulta. Como uma consulta pode ter vários cenários com workers ativos simultaneamente, o cronograma se destina a mostrar o progresso geral da consulta.

Como visualizar informações com a IU da Web clássica do BigQuery

Se você usa a IU da Web clássica do BigQuery, é possível ver detalhes do plano de uma consulta concluída. Basta clicar no botão Detalhes, à direita do botão Resultados.

Captura de tela do plano de consulta

Para consultas de longa duração, é possível ver o progresso do plano de consulta clicando no link na linha de status dela, abaixo do painel de composição.

Captura de tela da linha de status de tempo decorrido

Informações do plano de consulta

Na resposta da API, os planos de consulta são representados como uma lista de cenários de consulta, que expõem estatísticas de visão geral por cenário, informações detalhadas da etapa e classificações de cronologia de cenário. Nem todos os detalhes são renderizados na IU da Web, mas podem estar presentes nas respostas da API.

Visão geral do cenário

Os campos de visão geral de cada cenário podem incluir os seguintes itens :

Campo de API Descrição
id Código numérico exclusivo do cenário.
name Nome simples de resumo do cenário. As steps no cenário fornecem mais detalhes sobre 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 cenário 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.

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 Operação de classificação ou ordenação, inclui as chaves de coluna e a direçã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 cenários de consulta também fornecem classificações de cronologia por cenário, tanto em termos absolutos quanto relativos. Como cada cenário de execução representa trabalho realizado por um ou mais trabalhadores independentes, as informações são fornecidas nos tempos médio e do pior caso, representando o desempenho médio de todos os trabalhadores em um cenário, bem como o desempenho de cauda longa mais lento do trabalhador referente a uma determinada classificação. Além disso, os tempos médio e máximo são desmembrados nas representações absolutas e relativas. Para as estatísticas baseadas em proporção, os dados são fornecidos como uma fração do tempo mais longo gasto por qualquer worker em qualquer segmento.

A cronologia de cenário é apresentada na IU da Web clássica do BigQuery por meio de representações de cronologia relativa.

As informações de cronologia de cenário são relatadas da seguinte maneira:

Cronologia relativa Cronologia absoluta IU da Web clássica do BigQuery* Numerador da proporção**
waitRatioAvg waitMsAvg Barra em amarelo-escuro waitRatioAvg Tempo que o trabalho médio passou aguardando ser programado.
waitRatioMax waitMsMax Barra em amarelo waitRatioMax Tempo que o trabalho mais lento passou aguardando ser programado.
readRatioAvg readMsAvg Barra em roxo-escuro readRatioAvg Tempo que o trabalho médio passou lendo dados de entrada.
readRatioMax readMsMax Barra em roxo readRatioMax Tempo que o trabalho mais lento passou lendo dados de entrada.
computeRatioAvg computeMsAvg Barra em laranja-escuro computeRatioAvg Tempo que o trabalho médio passou ligado à CPU.
computeRatioMax computeMsMax Barra em laranja computeRatioMax Tempo que o trabalho mais lento passou ligado à CPU.
writeRatioAvg writeMsAvg Barra em azul-escuro writeRatioAvg Tempo que o trabalho médio passou gravando dados de saída.
writeRatioMax writeMsMax Barra em azul writeRatioMax Tempo que o worker mais lento passou gravando dados de saída.

*Os rótulos "AVG" e "MAX" são apenas ilustrativos. Eles não aparecem na IU da Web clássica do BigQuery.

Metadados do cronograma

O cronograma da consulta relata o progresso em pontos específicos no tempo, fornecendo visualizações instantâneas do progresso geral da consulta. O cronograma é representado como uma série de amostras, que relatam 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

Se você executar uma consulta simples que conta o número de linhas no conjunto de dados público de Shakespeare e uma segunda contagem condicional que restringe os resultados às linhas que fazem referência a Hamlet:

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

Você poderá clicar em Detalhes para ver as seguintes informações sobre o plano de consulta. Primeiro, vamos examinar a primeira seção, que contém o cronograma da consulta:

Captura de tela do cronograma de consulta de Hamlet

Neste exemplo, estamos lidando com uma tabela de exemplo muito pequena e uma consulta simples, portanto, há apenas duas unidades de trabalho. Com este exemplo, todo o trabalho é concluído quase imediatamente.

Então, vamos observar mais detalhadamente o plano de consulta:

Captura de tela do plano de consulta de Hamlet

Neste exemplo, as cores indicadoras mostram os intervalos de tempo relativos de todos os cenários. A partir das informações de entrada paralela, vemos que cada cenário exigiu apenas um único worker, portanto, não há variação entre o intervalo médio e o mais lento.

Também é possível ver que, para essa consulta trivial, o maior tempo em qualquer segmento foi o tempo que o único trabalhador no Cenário 01 gastou esperando a conclusão do Cenário 00. Isso ocorre porque o Cenário 01 era dependente da entrada do Cenário 00 e não podia ser iniciado até que o primeiro cenário gravasse a respectiva saída (1 linha, ~18 bytes) no embaralhamento intermediário.

Agora, serão examinadas as etapas dos nossos cenários de execução em mais detalhes. À esquerda do marcador do cenário, clique no triângulo para expandir os detalhes do cenário:

Captura de tela dos detalhes da etapa do plano de consulta de Hamlet

Nesse caso, podemos ver o plano de execução do único trabalhador que concluiu o trabalho do Cenário 00. Primeiro, os dados estavam como READ a partir da coluna "corpus" da tabela de Shakespeare referenciada. Em seguida, AGGREGATIONS foi estabelecido para as projeções COUNT e COUNTIF. A varredura dos dados exigiu uma etapa COMPUTE, que forneceu dados para as contagens normal e condicional, e a saída foi gravada na saída de embaralhamento intermediário, marcada como __stage00_output neste plano.

Relatórios de erros

É 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. Na IU, cenários bem-sucedidos e com falha são marcados por marca de seleção e ponto de exclamação ao lado do(s) nome(s) de cenário.

Para mais informações sobre interpretação e análise de 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 automaticamente às informações de resposta do job sem a necessidade de chamar outros métodos, podendo ser recuperadas com uma simples chamada a jobs.get para recuperar os detalhes do job. Por exemplo, abaixo temos um trecho de uma resposta JSON a um job que retorna a consulta de Hamlet de amostra. Ele mostra o plano de consulta e as informações de cronograma.

"statistics": {
  "query": {
    "cacheHit": false,
    "queryPlan": [
      {
        "completedParallelInputs": "1",
        "computeMsAvg": "25",
        "computeMsMax": "25",
        "computeRatioAvg": 0.17857142857142858,
        "computeRatioMax": 0.17857142857142858,
        "endMs": "1522787349945",
        "id": "0",
        "name": "S00: Input",
        "parallelInputs": "1",
        "readMsAvg": "28",
        "readMsMax": "28",
        "readRatioAvg": 0.2,
        "readRatioMax": 0.2,
        "recordsRead": "164656",
        "recordsWritten": "1",
        "shuffleOutputBytes": "18",
        "shuffleOutputBytesSpilled": "0",
        "startMs": "1522787349898",
        "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"
            ]
          }
        ],
        "waitMsAvg": "0",
        "waitMsMax": "0",
        "waitRatioAvg": 0.0,
        "waitRatioMax": 0.0,
        "writeMsAvg": "5",
        "writeMsMax": "5",
        "writeRatioAvg": 0.03571428571428571,
        "writeRatioMax": 0.03571428571428571
      },
      {
        "completedParallelInputs": "1",
        "computeMsAvg": "14",
        "computeMsMax": "14",
        "computeRatioAvg": 0.1,
        "computeRatioMax": 0.1,
        "endMs": "1522787350180",
        "id": "1",
        "inputStages": [
          "0"
        ],
        "name": "S01: Output",
        "parallelInputs": "1",
        "readMsAvg": "0",
        "readMsMax": "0",
        "readRatioAvg": 0.0,
        "readRatioMax": 0.0,
        "recordsRead": "1",
        "recordsWritten": "1",
        "shuffleOutputBytes": "16",
        "shuffleOutputBytesSpilled": "0",
        "startMs": "1522787350038",
        "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"
            ]
          }
        ],
        "waitMsAvg": "140",
        "waitMsMax": "140",
        "waitRatioAvg": 1.0,
        "waitRatioMax": 1.0,
        "writeMsAvg": "129",
        "writeMsMax": "129",
        "writeRatioAvg": 0.9214285714285714,
        "writeRatioMax": 0.9214285714285714
      }
    ],
    "referencedTables": [
      {
        "datasetId": "samples",
        "projectId": "publicdata",
        "tableId": "shakespeare"
      }
    ],
    "statementType": "SELECT",
    "timeline": [
      {
        "activeUnits": "0",
        "completedUnits": "2",
        "elapsedMs": "999",
        "pendingUnits": "0",
        "totalSlotMs": "185"
      },
      {
        "activeUnits": "0",
        "completedUnits": "2",
        "elapsedMs": "1197",
        "pendingUnits": "0",
        "totalSlotMs": "185"
      }
    ],
    "totalBytesBilled": "10485760",
    "totalBytesProcessed": "2464625",
    "totalPartitionsProcessed": "0",
    "totalSlotMs": "127"
  },
  "totalBytesProcessed": "2464625"
},

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 utilização de alguns detalhes. Muitas otimizações ocorrem automaticamente com o simples uso do serviço, o que pode diferir de outros ambientes em que o ajuste, o provisionamento e o monitoramento podem exigir uma equipe dedicada e capacitada.

Para técnicas específicas capazes de melhorar a execução e o desempenho de consultas, consulte a documentação de práticas recomendadas. O plano de consulta e as estatísticas de cronograma podem ajudar você a entender se determinados cenários dominam a utilização de recursos. Por exemplo, um cenário JOIN que gera muito mais linhas de saída que linhas de entrada pode indicar uma oportunidade para filtrar em um ponto anterior na consulta.

Além disso, as informações da linha do tempo podem ajudar a identificar se uma determinada consulta é lenta isoladamente ou devido a efeitos de outras consultas disputando os mesmos recursos. Se você observar que o número de unidades ativas permanece limitado durante todo o ciclo de vida da consulta, mas a quantidade de unidades de trabalho em fila permanece alta, talvez a redução do número de consultas simultâneas melhore significativamente o tempo de execução geral de determinadas consultas.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.