Análise de consultas usando o perfil de consulta

O perfil de consulta, disponível através da Classic Console, fornece detalhes de execução para uma consulta. Para a consulta selecionada, ele fornece uma representação gráfica dos principais componentes do plano de processamento da consulta, com estatísticas para cada componente, juntamente com detalhes e estatísticas para a consulta geral.

Neste tópico:

Introdução

Quando usar o perfil de consulta

O perfil de consulta é uma ferramenta poderosa para compreender a mecânica das consultas. Pode ser usado sempre que você quiser ou precisar saber mais sobre o desempenho ou comportamento de uma determinada consulta. É projetado para ajudar a detectar erros típicos em expressões de consulta SQL para identificar possíveis gargalos de desempenho e oportunidades de melhoria.

Informações adicionais de alto nível sobre consultas individuais podem ser visualizadas em várias colunas nas páginas Worksheets Worksheet tab e History History tab.

Como acessar o perfil de consulta

O perfil de consulta é acessado da página de detalhes para uma consulta. Como tal, você pode acessar o perfil de consulta de qualquer página onde a coluna Query ID é exibida e IDs de consulta podem ser clicadas, especificamente:

  • Worksheets Worksheet tab

  • History History tab

Nota

Se a coluna Query ID não for exibida nestas páginas, clique no menu suspenso ao lado de um dos cabeçalhos de coluna na página e, na lista de Columns, selecione Query ID.

Para acessar o perfil para uma consulta:

  1. Na página History History tab ou Worksheets Worksheet tab, clique em uma ID de consulta.

  2. A página de detalhes para a consulta é exibida:

    ../_images/ui-profile-detail.png
  3. Clique na guia Profile.

  4. Se a consulta tiver um perfil, ele é exibido (consulte as capturas de tela abaixo).

Interface do perfil de consulta

Para o propósito deste tópico, estamos usando um exemplo de consulta SQL básica que une duas tabelas:

select sum(j)
from x join y using (i)
where j > 300
and i < (select avg(j) from x);
Copy

A seguinte captura de tela mostra o perfil para esta consulta:

../_images/ui-profile-step1.png

A interface é composta dos seguintes elementos principais:

Etapas

Se a consulta foi processada em várias etapas, você pode alternar entre cada etapa.

Árvore do operador

O painel central exibe uma representação gráfica de todos os nós de operador para a etapa selecionada, incluindo as relações entre cada nó de operador.

Lista de nós

O painel do meio inclui uma lista recolhível de nós de operador por tempo de execução.

Visão geral

O painel direito exibe uma visão geral do perfil da consulta. A tela muda para detalhes do operador quando um nó de operador é selecionado.

Etapas

As consultas são frequentemente processadas em várias etapas. Por exemplo, nossa consulta de amostra foi processada em 2 etapas:

  • A etapa 1 calculou a média da coluna x.j.

  • A etapa 2 utilizou este resultado intermediário para calcular o resultado final da consulta.

O perfil de consulta exibe cada etapa de processamento em um painel separado. Você pode alternar entre os painéis clicando na respectiva etapa. Para nossa consulta de exemplo, clicar em Step 2 muda a exibição para:

../_images/ui-profile-step2.png

Árvore do operador

A árvore fornece uma representação gráfica dos nós do operador que compreendem uma consulta e os links que conectam cada operador:

  • Os operadores são os blocos de construção funcionais de uma consulta. Eles são responsáveis por diferentes aspectos do gerenciamento e processamento de dados, incluindo acesso aos dados, transformações e atualizações. Cada nó de operador na árvore inclui alguns atributos básicos:

    <Tipo> [nº]

    Tipo e número de ID do operador. A ID pode ser usada para identificar exclusivamente um operador dentro de um perfil de consulta (por exemplo, Aggregate [5] e Join [11] na captura de tela acima).

    Para descrições de todos os tipos, consulte Tipos de operadores abaixo.

    Porcentagem

    Fração de tempo que este operador consumiu dentro da etapa de consulta (por exemplo 25% para Aggregate [5]). Esta informação também se reflete na barra laranja na parte inferior do nó do operador, permitindo uma fácil identificação visual dos operadores com desempenho crítico.

    Rótulo

    Informações adicionais específicas do operador (por exemplo SUM(X.J) para Aggregate [5]).

  • Os links representam o fluxo de dados entre cada nó de operador. Cada link fornece o número de registros que foram processados (por exemplo, 41,95 M de Join [11] a Aggregate [5]).

Nota

Se você estiver usando uma tela sensível ao toque e a árvore do operador não for exibida, a interface de eventos de toque para sua tela sensível ao toque pode estar interferindo. Para obter instruções sobre como desativar temporariamente a interface, consulte a discussão no fórum da Comunidade Snowflake: A janela de perfil de consulta mostra a visão geral, mas não mostra a árvore de consulta..

Nós do operador por tempo de execução

Um painel recolhível no painel do operador lista os nós por tempo de execução em ordem decrescente, permitindo aos usuários localizar rapidamente os nós do operador mais caros em termos de tempo de execução. O painel lista todos os nós que duraram 1% ou mais do tempo total de execução da consulta (ou o tempo de execução da etapa de consulta exibida, se a consulta foi executada em múltiplas etapas de processamento).

Clicar em um nó da lista centraliza a árvore do operador no nó selecionado.

A seguinte captura de tela mostra o painel após clicar no operador Aggregate [5]:

../_images/ui-profile-nodes-by-execution-time.png

Visão geral do perfil/Detalhes do operador

O painel de visão geral/detalhes à direita fornece informações sobre os componentes selecionados (operadores e links) na árvore à esquerda. A informação exibida depende se um nó na árvore do operador é selecionado:

  • Inicialmente, nenhum nó na árvore é selecionado, portanto o painel mostra informações gerais para a etapa atual.

  • Quando um componente é selecionado clicando sobre o nó, o painel mostra informações para o componente.

Nota

Após clicar em um nó, para retornar às informações de síntese em nível de etapa, simplesmente desmarque o nó clicando em qualquer espaço vazio ao redor da árvore do operador.

O painel de visão geral/detalhes é dividido em 3 seções:

Tempo de execução

Fornece informações sobre quais tarefas de processamento consumiram tempo de consulta (descritas em Detalhes da consulta/operador abaixo). Além disso, para informações em nível de etapa, mostra o estado da etapa dada e seu tempo de execução.

Estatísticas

Fornece informações detalhadas sobre várias estatísticas (descritas em Detalhes da consulta/operador abaixo).

Atributos

Fornece informações específicas do componente (descritas em Tipos de operadores abaixo).

A seguinte captura de tela mostra os detalhes após clicar no operador Join [11]:

../_images/ui-profile-operator.png

Tipos de operadores

As seções seguintes fornecem uma lista dos tipos de operadores mais comuns e seus atributos.

Operadores de geração e acesso a dados

TableScan

Representa o acesso a uma única tabela. Atributos:

  • Full table name — o nome da tabela acessada, incluindo banco de dados e esquema.

  • Columns — lista de colunas verificadas

  • Table alias — usado, se presente

  • Extracted Variant paths — lista de caminhos extraídos das colunas VARIANT

ValuesClause

Lista de valores fornecidos com a cláusula VALUES. Atributos:

  • Number of values — o número de valores produzidos.

  • Values — a lista de valores produzidos.

Gerador

Gera registros usando o constructo TABLE(GENERATOR(...)). Atributos:

  • rowCount — parâmetro rowCount fornecido.

  • timeLimit — parâmetro timeLimit fornecido.

ExternalScan

Representa o acesso a dados armazenados em objetos de preparação. Pode ser uma parte das consultas que verificam dados diretamente dos estágios, mas também para consultas COPY de carregamento de dados. Atributos:

  • Stage name — o nome do estágio de onde os dados são lidos.

  • Stage type — o tipo do estágio (por exemplo, TABLE STAGE).

InternalObject

Representa o acesso a um objeto de dados interno (por exemplo, uma tabela de Information Schema ou o resultado de uma consulta anterior). Atributos:

  • Object Name — o nome ou tipo do objeto acessado.

Operadores de processamento de dados

Filter

Representa uma operação que filtra os registros. Atributos:

  • Filter condition - a condição utilizada para realizar a filtragem.

Join

Combina duas entradas em uma determinada condição. Atributos:

  • Join Type — Tipo de junção (por exemplo, INNER, LEFT OUTER, etc.).

  • Equality Join Condition — para as junções que utilizam condições baseadas na igualdade, lista as expressões utilizadas para unir elementos.

  • Additional Join Condition — algumas condições de junção contêm predicados baseadas em desigualdade. Elas estão listadas aqui.

Nota

Predicados de junção de desigualdade podem resultar em velocidades de processamento significativamente mais lentas e devem ser evitados, se possível.

Agregação

Agrupa entradas e computa funções agregadas. Pode representar constructos SQL como GROUP BY, assim como SELECT DISTINCT. Atributos:

  • Grouping Keys — se GROUP BY for usado, lista as expressões pelas quais agrupamos.

  • Aggregate Functions — lista de funções computadas para cada grupo agregado, por exemplo SUM.

GroupingSets

Representa construtos como GROUPING SETS, ROLLUP e CUBE. Atributos:

  • Grouping Key Sets — lista de conjuntos de agrupamento

  • Aggregate Functions — lista de funções computadas para cada grupo, por exemplo SUM.

WindowFunction

Computa funções de janela. Atributos:

  • Window Functions — lista de funções de janela computadas.

Sort

Ordena a entrada em uma determinada expressão. Atributos:

  • Sort Keys — expressão que define a classificação.

SortWithLimit

Produz uma parte da sequência de entrada após a classificação, normalmente um resultado de um constructo ORDER BY ... LIMIT ... OFFSET ... em SQL. Atributos:

  • Sort Keys — expressão que define a classificação.

  • Number of rows — número de linhas produzidas.

  • Offset — posição na sequência ordenada a partir da qual as tuplas produzidas são emitidas.

Flatten

Processa registros VARIANT, possivelmente nivelando-os em um caminho especificado. Atributos:

  • input — a expressão de entrada usada para nivelar os dados.

JoinFilter

Operação de filtragem especial que remove tuplas que podem ser identificadas como possivelmente não correspondendo à condição de um Join mais além no plano da consulta. Atributos:

  • Original join ID — a junção usada para identificar tuplas que podem ser filtradas.

UnionAll

Concatena duas entradas. Atributos: nenhum.

ExternalFunction

Representa o processamento por uma função externa.

Operadores DML

Insert

Adiciona registros a uma tabela através de uma operação INSERT ou COPY. Atributos:

  • Input expressions — quais expressões são inseridas.

  • Nome completo da tabela — nome da tabela de destino única à qual os registros são adicionados.

  • Full table names — nomes de várias tabelas de destino às quais os registros são adicionados.

Delete

Remove registros de uma tabela. Atributos:

  • Full table name — o nome da tabela da qual os registros são excluídos.

Update

Atualiza os registros em uma tabela. Atributos:

  • Full table name — o nome da tabela atualizada.

Merge

Realiza uma operação MERGE em uma tabela. Atributos:

  • Full table name — o nome da tabela atualizada.

Unload

Representa uma operação COPY que exporta dados de uma tabela para um arquivo em um estágio. Atributos:

  • Location - o nome do estágio onde os dados são salvos.

Operadores de metadados

Algumas consultas incluem etapas que são puras operações de metadados/catálogos em vez de operações de processamento de dados. Estas etapas consistem em um único operador. Alguns exemplos incluem:

Comandos DDL e de transação

Usados para criar ou modificar objetos, sessões, transações, etc. Normalmente, estas consultas não são processadas por um warehouse virtual e resultam em um perfil de etapa única que corresponde à instrução SQL correspondente. Por exemplo:

CREATE DATABASE | SCHEMA | …

ALTER DATABASE | SCHEMA | TABLE | SESSION | …

DROP DATABASE | SCHEMA | TABLE | …

COMMIT

Comando de criação de tabelas

Comando DDL para a criação de uma tabela. Por exemplo:

CREATE TABLE

Similar a outros comandos DDL, estas consultas resultam em um perfil de etapa única; no entanto, também podem fazer parte de um perfil de múltiplas etapas, como quando usadas em uma instrução CTAS. Por exemplo:

CREATE TABLE … AS SELECT …

Reutilização do resultado da consulta

Uma consulta que reutiliza o resultado de uma consulta anterior.

Resultado baseado em metadados

Uma consulta cujo resultado é computado puramente com base em metadados, sem acessar nenhum dado. Estas consultas não são processadas por um warehouse virtual. Por exemplo:

SELECT COUNT(*) FROM …

SELECT CURRENT_DATABASE()

Operadores diversos

Resultado

Retorna o resultado da consulta. Atributos:

  • List of expressions - as expressões produzidas.

Detalhes da consulta/operador

Para ajudá-lo a analisar o desempenho da consulta, o painel de detalhes fornece duas classes de informações de perfil:

  • Tempo de execução, dividido em categorias

  • Estatísticas detalhadas

Além disso, são fornecidos atributos para cada operador (descritos em Tipos de operadores neste tópico).

Tempo de execução

O tempo de execução fornece informações sobre “onde o tempo foi gasto” durante o processamento de uma consulta. O tempo gasto pode ser dividido nas seguintes categorias, exibidas na seguinte ordem:

  • Processing — tempo gasto no processamento de dados pela CPU.

  • Local Disk IO — hora em que o processamento foi bloqueado pelo acesso a disco local.

  • Remote Disk IO — hora em que o processamento foi bloqueado pelo acesso a disco remoto.

  • Network Communication — tempo em que o processamento aguardava a transferência dos dados da rede.

  • Synchronization — diversas atividades de sincronização entre os processos participantes.

  • Initialization — tempo gasto na preparação do processamento da consulta.

Estatísticas

Uma das principais fontes de informações fornecidas no painel de detalhes são as diversas estatísticas, agrupadas nas seções seguintes:

  • IO — informações sobre as operações de entrada-saída realizadas durante a consulta:

    • Scan progress — a porcentagem de dados verificados para uma determinada tabela até o momento.

    • Bytes scanned — o número de bytes verificados até o momento.

    • Percentage scanned from cache — a porcentagem de dados verificados a partir do cache do disco local.

    • Bytes written — bytes gravados (por exemplo, ao carregar em uma tabela).

    • Bytes written to result — bytes gravados no objeto de resultado. Por exemplo, select * from . . . produziria um conjunto de resultados em formato tabular representando cada campo na seleção. Em geral, o objeto de resultado representa tudo o que é produzido como resultado da consulta, e Bytes gravados no resultado representa o tamanho do resultado retornado.

    • Bytes read from result — bytes lidos do objeto de resultado.

    • External bytes scanned — bytes lidos a partir de um objeto externo, por exemplo, um estágio.

  • DML — estatísticas para consultas de linguagem de manipulação de dados (DML):

    • Number of rows inserted — número de linhas inseridas em uma tabela (ou tabelas).

    • Number of rows updated — número de linhas atualizadas em uma tabela.

    • Number of rows deleted — número de linhas excluídas de uma tabela.

    • Number of rows unloaded — número de linhas descarregadas durante a exportação de dados.

  • Pruning — informações sobre os efeitos da remoção realizada na tabela:

    • Partitions scanned — número de partições verificadas até o momento.

    • Partitions total — número total de partições em uma determinada tabela.

  • Spilling — informações sobre o uso do disco para operações onde os resultados intermediários não cabem na memória:

    • Bytes spilled to local storage — volume de dados despejados para o disco local.

    • Bytes spilled to remote storage — volume de dados despejados no disco remoto.

  • Network — comunicação em rede:

    • Bytes sent over the network — quantidade de dados enviados pela rede.

  • External Functions — informações sobre chamadas para funções externas:

    As seguintes estatísticas são mostradas para cada função externa chamada pela instrução SQL. Se a mesma função foi chamada mais de uma vez a partir da mesma instrução SQL, então as estatísticas são agregadas.

    • Total invocations — número de vezes que uma função externa foi chamada. (Isto pode ser diferente do número de chamadas de funções externas no texto da instrução SQL devido ao número de lotes em que as linhas estão divididas, o número de novas tentativas (se houver problemas transitórios na rede), etc.)

    • Rows sent — número de linhas enviadas para funções externas.

    • Rows received — número de linhas recebidas de volta das funções externas.

    • Bytes sent (x-region) — número de bytes enviados para funções externas. Se o rótulo incluir “(x-region)”, os dados foram enviados através de regiões (o que pode ter impacto no faturamento).

    • Bytes received (x-region) — número de bytes recebidos de funções externas. Se o rótulo incluir “(x-region)”, os dados foram enviados através de regiões (o que pode ter impacto no faturamento).

    • Retries due to transient errors — número de tentativas de repetição devido a erros transitórios.

    • Average latency per call — média de tempo por invocação (chamada) entre o momento em que Snowflake enviou os dados e o recebimento dos dados devolvidos.

    • HTTP 4xx erros — número total de solicitações de HTTP que retornaram um código de status 4xx.

    • HTTP 5xx erros — número total de solicitações de HTTP que retornaram um código de status 5xx.

    • Latency per successful call (avg) — latência média para solicitações de HTTP bem-sucedidas.

    • Avg throttle latency overhead — sobretaxa média por solicitação bem-sucedida devido a uma desaceleração causada pela limitação (HTTP 429).

    • Batches retried due to throttling — número de lotes que foram repetidos devido a erros HTTP 429.

    • Latency per successful call (P50) — latência de percentil 50 para solicitações de HTTP bem-sucedidas. 50 por cento de todas as solicitações bem-sucedidas levaram menos do que esse tempo para serem concluídas.

    • Latency per successful call (P90) — latência de percentil 90 para solicitações de HTTP bem-sucedidas. 90 por cento de todas as solicitações bem-sucedidas levaram menos do que esse tempo para serem concluídas.

    • Latency per successful call (P95) — latência de percentil 95 para solicitações de HTTP bem-sucedidas. 95 por cento de todas as solicitações bem-sucedidas levaram menos do que esse tempo para serem concluídas.

    • Latency per successful call (P99) — latência de percentil 99 para solicitações de HTTP bem-sucedidas. 99 por cento de todas as solicitações bem-sucedidas levaram menos do que esse tempo para serem concluídas.

  • Extension Functions — informações sobre chamadas para funções de extensão:

    • Java UDF handler load time – quantidade de tempo para o manipulador da UDF de Java carregar.

    • Total de invocações do manipulador da UDF de Java — número de vezes que o manipulador da UDF de Java é invocado.

    • Max Java UDF handler execution time — quantidade de tempo máxima para que o manipulador da UDF de Java seja executado.

    • Avg Java UDF handler execution time — quantidade média de tempo para executar o manipulador da UDF de Java.

    • Java UDTF process() invocations — número de vezes que o método de processo da UDTF foi invocado.

    • Java UDTF process() execution time — quantidade de tempo para executar o processo da UDTF de Java.

    • Avg Java UDTF process() execution time — quantidade média de tempo para executar o processo da UDTF de Java.

    • Java UDTF’s constructor invocations — número de vezes que o construtor da UDTF foi invocado.

    • Java UDTF’s constructor execution time — quantidade de tempo para executar o construtor da UDTF de Java.

    • Avg Java UDTF’s constructor execution time — quantidade média de tempo para executar o construtor da UDTF de Java.

    • Java UDTF endPartition() invocations — número de vezes que o método endPartition da UDTF foi invocado.

    • Java UDTF endPartition() execution time — quantidade de tempo para executar o método endPartition da UDTF de Java.

    • Avg Java UDTF endPartition() execution time — quantidade média de tempo para executar o método endPartition da UDTF de Java.

    • Max Java UDF dependency download time — quantidade máxima de tempo para baixar as dependências da UDF de Java.

    • Max JVM memory usage — pico de uso de memória conforme relatado pelo JVM.

    • Java UDF inline code compile time in ms — tempo de compilação para o código inline da UDF de Java.

    • Python total UDF invocações do manipulador — número de vezes que o manipulador da UDF de Python foi invocado.

    • Total Python UDF handler execution time — tempo total de execução do manipulador da UDF de Python.

    • Avg Python UDF handler execution time — quantidade média de tempo para executar o manipulador da UDF de Python.

    • Python sandbox max memory usage — pico de uso de memória pelo ambiente sandbox do Python.

    • Avg Python env creation time: Download and install packages — quantidade média de tempo para criar o ambiente Python, incluindo download e instalação de pacotes.

    • Conda solver time — quantidade de tempo para executar o solucionador Conda para resolver pacotes Python.

    • Conda env creation time — quantidade de tempo para criar o ambiente Python.

    • Python UDF initialization time — quantidade de tempo para inicializar a UDF de Python.

    • Number of external file bytes read for UDFs — número de bytes de arquivos externos lidos para UDFs.

    • Number of external files accessed for UDFs — número de arquivos externos acessados para UDFs.

    Se o valor de um campo, por exemplo “Retries due to transient errors”, for zero, então o campo não é exibido.

Problemas comuns de consulta identificados pelo perfil de consulta

Esta seção descreve alguns dos problemas que você pode identificar e solucionar usando o perfil de consulta.

“Explosão” de junções

Um dos erros comuns dos usuários de SQL é unir tabelas sem fornecer uma condição de junção (resultando em um “produto cartesiano”), ou fornecer uma condição em que os registros de uma tabela correspondem a vários registros de outra tabela. Para tais consultas, o operador Join produz significativamente (muitas vezes por ordem de magnitude) mais tuplas do que consome.

Isto pode ser observado verificando o número de registros produzidos por um operador Join, e normalmente também se reflete em um operador Join que consome muito tempo.

O exemplo seguinte mostra a entrada em centenas de registros, mas a saída em centenas de milhares:

SELECT tt1.c1, tt1.c2
FROM tt1
JOIN tt2 ON tt1.c1 = tt2.c1
 AND tt1.c2 = tt2.c2;
Copy
../_images/ui-profile-issues-exploding-joins.png

UNION sem ALL

Em SQL, é possível combinar dois conjuntos de dados com constructos UNION ou UNION ALL. A diferença entre eles é que UNION ALL simplesmente concatena as entradas, enquanto UNION faz o mesmo, mas também realiza a eliminação de duplicatas.

Um erro comum é usar UNION quando a semântica UNION ALL é suficiente. Estas consultas aparecem no perfil de consulta como um operador UnionAll com um operador extra Aggregate por cima (que realiza a eliminação de duplicatas).

Consultas grandes demais para caber na memória

Para algumas operações (por exemplo, eliminação de duplicatas para um conjunto de dados grande), a quantidade de memória disponível para os servidores usados para os recursos de computação pode não ser suficiente para armazenar resultados intermediários. Como resultado, o mecanismo de processamento de consultas começará a despejar os dados no disco local. Se o espaço em disco local não for suficiente, os dados despejados são salvos em discos remotos.

Este despejo pode ter um efeito profundo no desempenho da consulta (especialmente se for utilizado disco remoto para despejo). Para sanar isso, recomendamos:

  • Usar um warehouse maior (aumentando efetivamente a memória disponível/espaço em disco local para a operação), e/ou

  • Processar dados em lotes menores.

Remoção ineficiente

O Snowflake coleta estatísticas ricas em dados, permitindo não ler partes desnecessárias de uma tabela com base nos filtros de consulta. Entretanto, para que isso tenha efeito, a ordem do armazenamento de dados precisa ser correlacionada com os atributos do filtro de consulta.

A eficiência da remoção pode ser observada comparando as estatísticas de partições verificadas e partições totais nos operadores TableScan. Se a primeira for uma pequena fração da segunda, a remoção foi eficiente. Caso contrário, não teve efeito.

Naturalmente, a remoção só pode ajudar para consultas que realmente filtram uma quantidade significativa de dados. Se as estatísticas de remoção não mostram redução de dados, mas há um operador Filter acima de TableScan que filtra uma série de registros, isto pode sinalizar que uma organização de dados diferente pode ser benéfica para esta consulta.

Para obter mais informações sobre remoção, consulte Explicação das estruturas de tabela do Snowflake.