Skip to main content
Mostra o plano de execução de uma instrução.
Sintaxe:
Exemplo:

Tipos de EXPLAIN

  • AST — Árvore de sintaxe abstrata.
  • SYNTAX — Texto da consulta após otimizações no nível da AST.
  • QUERY TREE — Árvore de consulta após otimizações no nível da árvore de consulta.
  • PLAN — Plano de execução da consulta.
  • PIPELINE — Pipeline de execução da consulta.
  • ANALYZE — Executa a consulta e anota o plano de execução com métricas de runtime medidas.
  • ESTIMATE — Número estimado de linhas, marcas e partes a serem lidas das tabelas durante o processamento da consulta.
  • TABLE OVERRIDE — Resultado validado de um override de tabela em um esquema de função de tabela.

EXPLAIN AST

Exibe a AST da consulta. Compatível com todos os tipos de consulta, não apenas SELECT. Configurações:
  • graph – Exibe a AST como um grafo descrito na linguagem de descrição de grafos DOT. Padrão: 0.
Exemplos:

EXPLAIN SYNTAX

Mostra a Árvore de Sintaxe Abstrata (AST) de uma consulta após a análise de sintaxe. Isso é feito fazendo o parsing da consulta, construindo a AST e a árvore de consulta da consulta, opcionalmente executando o analisador de consultas e os passes de otimização, e então convertendo a árvore de consulta de volta para a AST da consulta. Configurações:
  • oneline – Imprime a consulta em uma única linha. Padrão: 0.
  • run_query_tree_passes – Executa os passes da árvore de consulta antes de exibi-la. Padrão: 0.
  • query_tree_passes – Se run_query_tree_passes estiver definido, especifica quantos passes executar. Sem especificar query_tree_passes, ele executa todos os passes.
Exemplos:
Query
Response
Usando run_query_tree_passes:
Query
Response

EXPLAIN QUERY TREE

Configurações:
  • run_passes — Executa todos os passes da árvore de consulta antes de exibir a árvore de consulta. Padrão: 1.
  • dump_passes — Exibe informações sobre os passes usados antes de exibir a árvore de consulta. Padrão: 0.
  • passes — Especifica quantos passes devem ser executados. Se definido como -1, executa todos os passes. Padrão: -1.
  • dump_tree — Exibe a árvore de consulta. Padrão: 1.
  • dump_ast — Exibe a AST da consulta gerada a partir da árvore de consulta. Padrão: 0.
Exemplo:

EXPLAIN PLAN

Exibe os passos do plano de consulta. Configurações:
  • optimize — Controla se as otimizações do plano de consulta são aplicadas antes da exibição do plano. Padrão: 1.
  • header — Exibe o cabeçalho de saída do passo. Padrão: 0.
  • description — Exibe a descrição do passo. Padrão: 1.
  • indexes — Mostra os índices usados, o número de partes filtradas e o número de grânulos filtrados para cada índice aplicado. Padrão: 0. Compatível com tabelas MergeTree. A partir do ClickHouse >= v25.9, esta instrução só exibe uma saída adequada quando usada com SETTINGS use_query_condition_cache = 0, use_skip_indexes_on_data_read = 0.
  • projections — Mostra todas as projeções analisadas e seu efeito na filtragem no nível de partes com base nas condições da chave primária da projeção. Para cada projeção, esta seção inclui estatísticas como o número de partes, linhas, marcas e intervalos avaliados usando a chave primária da projeção. Também mostra quantas partes de dados foram ignoradas devido a essa filtragem, sem ler a própria projeção. Se uma projeção foi realmente usada para leitura ou apenas analisada para filtragem pode ser determinado pelo campo description. Padrão: 0. Compatível com tabelas MergeTree.
  • actions — Exibe informações detalhadas sobre as ações do passo. Padrão: 1.
  • sorting — Exibe a descrição da ordenação para cada passo do plano que produz saída ordenada. Padrão: 0.
  • keep_logical_steps — Mantém os passos lógicos do plano para junções em vez de convertê-los em implementações físicas de junção. Padrão: 0.
  • json — Exibe os passos do plano de consulta como uma linha no formato JSON. Padrão: 0. Recomenda-se usar o formato TabSeparatedRaw (TSVRaw) para evitar escapes desnecessários.
  • input_headers — Exibe os cabeçalhos de entrada do passo. Padrão: 0. Em geral, isso só é útil para desenvolvedores depurarem problemas relacionados à incompatibilidade entre cabeçalhos de entrada e saída.
  • column_structure — Exibe também a estrutura das colunas nos cabeçalhos, além do nome e do tipo. Padrão: 0. Em geral, isso só é útil para desenvolvedores depurarem problemas relacionados à incompatibilidade entre cabeçalhos de entrada e saída.
  • distributed — Mostra os planos de consulta executados em nós remotos para tabelas distribuídas ou réplicas paralelas. Não é compatível com json. Padrão: 0.
  • compact — Quando ativado, oculta do plano os passos de expressão e as informações detalhadas das ações (entradas, funções, aliases e posições de saída). Só tem efeito quando actions = 1. Padrão: 1.
  • pretty — Exibe a árvore do plano usando caracteres de desenho de linha (├──, └──, │) em vez de indentação para visualizar a hierarquia. Também formata as propriedades do passo de junção em linha. Padrão: 1.
Por padrão, explain_query_plan_default = 'pretty', portanto actions, compact e pretty são inicializados com 1, e o plano é renderizado na forma compacta, com formatação pretty e com anotações de ações. Especificar explicitamente qualquer uma dessas opções na instrução EXPLAIN (por exemplo, EXPLAIN actions = 0, compact = 0, pretty = 0 SELECT ...) sempre substitui o padrão.Antes do ClickHouse 26.7, os valores padrão de actions, compact e pretty eram 0. Você ainda pode obter essa saída definindo explain_query_plan_default = 'legacy' (globalmente ou em SETTINGS por consulta) ou definindo compatibility para qualquer versão anterior à 26.7.As opções json e distributed não habilitam os padrões de pretty (actions, compact e pretty), mesmo quando explain_query_plan_default = 'pretty'. Para incluir detalhes das ações na saída delas, defina actions = 1 manualmente.
Exemplo:
Não há suporte à estimativa de custo do passo e da consulta.
Quando json = 1, o plano da consulta é representado em formato JSON. Cada nó é um dicionário que sempre tem as chaves Node Type, Node Id e Plans. Node Type é uma string com o nome do passo, e Node Id é um identificador exclusivo do passo (o nome do passo com um sufixo numérico, por exemplo, Union_10). Plans é um array com descrições dos passos filhos. Outras chaves opcionais podem ser adicionadas dependendo do tipo de nó e das configurações. Exemplo:
Com description = 1, a chave Description é adicionada ao passo:
Com header = 1, a chave Header é adicionada ao passo na forma de um array de colunas. Exemplo:
Com indexes = 1, a chave Indexes é adicionada. Ela contém um array dos índices usados. Cada índice é descrito como JSON com a chave Type (uma string Partition Min-Max, Partition, Statistics, PrimaryKey ou Skip) e chaves opcionais:
  • Name — O nome do índice (atualmente usado apenas para índices Skip).
  • Keys — O array de colunas usado pelo índice.
  • Condition — A condição usada.
  • Description — A descrição do índice (atualmente usada apenas para índices Skip).
  • Parts — O número de partes após/antes da aplicação do índice.
  • Granules — O número de grânulos após/antes da aplicação do índice.
  • Ranges — O número de intervalos de grânulos após a aplicação do índice.
Exemplo:
Com projections = 1, a chave Projections é adicionada. Ela contém um array de projeções analisadas. Cada projeção é descrita como JSON com as seguintes chaves:
  • Name — O nome da projeção.
  • Condition — A condição da chave primária usada pela projeção.
  • Description — A descrição de como a projeção é usada (por exemplo, filtragem em nível de partes).
  • Selected Parts — Número de partes selecionadas pela projeção.
  • Selected Marks — Número de marcas selecionadas.
  • Selected Ranges — Número de intervalos selecionados.
  • Selected Rows — Número de linhas selecionadas.
  • Filtered Parts — Número de partes ignoradas devido à filtragem em nível de partes.
Exemplo:
Com actions = 1, as chaves adicionadas dependem do tipo de passo. Exemplo:
Com compact = 0 e actions = 1, os passos de Expression podem ser vistos juntamente com informações detalhadas sobre as expressões:
Com distributed = 1, a saída inclui não apenas o plano de consulta local, mas também os planos de consulta que serão executados nos nós remotos. Isso é útil para analisar e depurar consultas distribuídas.
distributed é exibido apenas na forma legacy (sem pretty), porque a saída pretty não integra os planos de shard remotos à árvore do plano. Por esse motivo, habilitar distributed desabilita automaticamente os padrões de pretty (actions, compact e pretty), independentemente de explain_query_plan_default. Você ainda pode definir actions=1 manualmente. A opção distributed também não é compatível com json.
Exemplo com tabela distribuída:
Exemplo com réplicas paralelas:
Em ambos os exemplos, o plano de consulta exibe o fluxo de execução completo, incluindo etapas locais e remotas. Com pretty = 1, a árvore do plano é exibida usando caracteres de desenho de linhas em vez de recuo, e informações adicionais são mostradas para os passos principais:
  • As colunas de saída da consulta são exibidas no topo do plano.
  • Expressões em filtros, chaves de agregação, descrições de ordenação e funções de janela são exibidas em uma notação semelhante a SQL legível por humanos (por exemplo, a + 1 > 5 em vez de greater(plus(a, 1), 5)). Os prefixos internos de identificadores de coluna (como __table1.) são removidos para maior clareza.
  • Passos de origem (como ReadFromMergeTree) exibem suas colunas de saída.
  • Passos de filtro exibem a condição de filtro em notação SQL. Quando há filtros de join em tempo de execução, eles são mostrados separadamente.
  • Passos de agregação exibem chaves e funções de agregação com seus argumentos (por exemplo, sum(c), count()).
  • Conjuntos de IN de literais Tuple mostram seus valores (truncados para conjuntos grandes), conjuntos baseados em subconsulta são rotulados como subquery1, subquery2 etc., e conjuntos de tabelas com o motor Set mostram o nome da tabela.
  • Passos de join exibem a relação de join usando notação matemática, a contagem estimada de linhas do resultado, e quais colunas de saída vêm do lado esquerdo e do lado direito. Os símbolos a seguir são usados para representar diferentes tipos de join:
Por exemplo, t1 ⟕ t2 significa uma junção à esquerda entre as tabelas t1 e t2. O número entre colchetes após o nome da tabela (por exemplo, t1[100]) indica a contagem estimada de linhas quando há estatísticas da tabela disponíveis. A opção pretty funciona bem em conjunto com compact = 1, que oculta os passos Expression e as informações detalhadas de ações, tornando o plano mais fácil de ler. Um exemplo detalhado com junções:

EXPLAIN PIPELINE

Configurações:
  • header — Imprime o cabeçalho de cada porta de saída. Padrão: 0.
  • graph — Imprime um grafo descrito na linguagem de descrição de grafos DOT. Padrão: 0.
  • compact — Imprime o grafo no modo compacto se a configuração graph estiver habilitada. Padrão: 1.
  • compact_repeated_processor_chains — Compacta cadeias repetidas adjacentes de processadores na saída de texto, mostrando uma cópia da cadeia com uma contagem de repetições. Isso pode facilitar a leitura de pipelines paralelos quando a mesma cadeia aparece muitas vezes, por exemplo, em junções. Isso não afeta a saída do grafo. Padrão: 0.
Quando compact=0 e graph=1, os nomes dos processadores conterão um sufixo adicional com um identificador exclusivo do processador. Exemplo:

EXPLAIN ANALYZE

EXPLAIN ANALYZE de fato executa a consulta, descarta as linhas de resultado e imprime a mesma árvore de plano que EXPLAIN PLAN, com cada passo anotado com o que realmente aconteceu em tempo de execução. Configurações: EXPLAIN ANALYZE aceita as mesmas opções de exibição que EXPLAIN PLAN (documentadas na seção EXPLAIN PLAN).
  • header — consulte a seção EXPLAIN PLAN.
  • description — consulte a seção EXPLAIN PLAN.
  • projections — consulte a seção EXPLAIN PLAN.
  • sorting — consulte a seção EXPLAIN PLAN.
  • input_headers — consulte a seção EXPLAIN PLAN.
  • column_structure — consulte a seção EXPLAIN PLAN.
  • actions — consulte a seção EXPLAIN PLAN. Padrão: 1.
  • indexes — consulte a seção EXPLAIN PLAN. Padrão: 1.
  • compact — consulte a seção EXPLAIN PLAN. Padrão: 1.
  • pretty — consulte a seção EXPLAIN PLAN. Padrão: 1.
  • processors — Para EXPLAIN ANALYZE, imprime uma linha adicional por estágio com a distribuição do tempo decorrido por processador: min, median, max e sum. Útil para identificar desequilíbrio de carga entre processadores paralelos. Padrão: 0.
Como EXPLAIN ANALYZE realmente executa a consulta encapsulada, ele se comporta como essa consulta — e, diferentemente das formas EXPLAIN que não executam — de várias maneiras:
  • Cotas e limites. Ele é contabilizado nas mesmas quotas e está sujeito aos mesmos limits (por exemplo, query_selects, read_rows) que a execução direta da consulta. Fontes isentas de cotas durante o planejamento (como system.one) não são contabilizadas.
  • Transações com falha. Dentro de uma transação que já falhou (ROLLED_BACK), ele é rejeitado com INVALID_TRANSACTION, assim como uma instrução SELECT simples — emita ROLLBACK primeiro.
  • Leituras de streaming. Em uma leitura de streaming (FROM ... STREAM), ele é rejeitado com NOT_IMPLEMENTED, porque esse tipo de leitura nunca termina.
  • Consultas distribuídas. Não há suporte para ele em consultas executadas em modo Distributed.
Exemplo:
Vamos examinar a saída. Primeiro, vamos ver o cabeçalho.
  • Time — tempo total dividido entre as fases de planejamento (isto é, criação do plano + otimização do plano + construção do pipeline) e execução (execução do pipeline).
  • Read — linhas e bytes não comprimidos lidos das tabelas, com a taxa de transferência — os mesmos números que o rodapé padrão da consulta informa como “Processed”.
  • Peak memory — pico de memória usado pela consulta.
Agora vamos examinar as novas linhas que aparecem no plano da consulta.
Linhas e bytes são informados uma vez para todo o passo (a linha I/O). O tempo e o paralelismo são informados por estágio do passo nas linhas indentadas abaixo.
  • rows <in> → <out> — linhas que entraram e saíram do passo; (<selectivity>%) mostra o quanto o passo filtrou (out/in) ou expandiu os dados; fica oculto quando as linhas de entrada são iguais às linhas de saída e quando as linhas de entrada são iguais a 0.
  • <bytes_in> → <bytes_out> — bytes não comprimidos em memória que passam pelo passo (omitido quando ambos são zero).
  • time <t> (<share>%) — tempo de relógio em que o estágio esteve ativo e sua participação no tempo de execução da consulta (isto é, sem o tempo de compilação). Observe que as participações podem somar mais de 100%, porque estágios e passos são executados de forma concorrente.
  • parallelism <avg>/<max> — número médio de threads de CPU trabalhando ao mesmo tempo neste estágio, do máximo que ele poderia usar. Um valor próximo do máximo significa que o estágio foi bem paralelizado; próximo de 1 significa que ele foi executado principalmente de forma serial.
  • Stage (<stage>) — o nome do estágio. Um passo com um único estágio imprime a linha de tempo diretamente, sem um rótulo Stage (...). Passos com vários estágios imprimem uma linha identificada para cada estágio; por exemplo, Aggregating mostra Stage (partial aggregation) e Stage (final aggregation), e um hash join mostra Stage (build) e Stage (probe).
O ClickHouse paraleliza não apenas a execução de tarefas dentro de um passo do plano, mas também a execução dos próprios passos do plano. A métrica parallelism reflete apenas o trabalho deste passo. Outros passos podem ser executados de forma concorrente, portanto esse número não mostra como o paralelismo do passo se compara ao da consulta como um todo.
O número máximo em parallelism é calculado como o valor mínimo entre:
  1. o número total de tarefas dentro do passo do plano;
  2. o número máximo de threads de processamento de consultas definido em max_threads.
Com processors = 1, uma linha extra é impressa abaixo de cada estágio, mostrando a distribuição do tempo decorrido entre os processadores do estágio:
<n> é o número de processadores no estágio. Uma grande diferença entre median e max indica um desequilíbrio de carga entre processadores paralelos.

EXPLAIN ESTIMATE

Mostra o número estimado de linhas, marcas e partes que serão lidas das tabelas durante o processamento da consulta. Funciona com tabelas da família MergeTree. Exemplo Criando uma tabela:
Query
Query
Response

EXPLAIN WHATIF

Estima o benefício que um skip index hipotético teria em uma consulta SELECT, sem materializar o índice em disco. Defina um ou mais candidatos com CREATE HYPOTHETICAL INDEX e, em seguida, execute EXPLAIN WHATIF SELECT ... para ver, para cada candidato: aplicabilidade, marcas lidas estimadas, bytes estimados e taxa de descarte. Sintaxe
Configurações
  • empirical1 (padrão) executa o índice em memória sobre os grânulos filtrados pela referência para medir a taxa de descarte (um limite superior). 0 ignora esse caminho. De qualquer forma, se empirical não produzir um resultado (por estar desabilitado ou porque o índice não pode ser avaliado em memória), o estimador recorre às estatísticas da coluna e, por fim, a um resumo apenas de aplicabilidade se nenhuma das duas opções estiver disponível.
Saída
  • source — como a estimativa foi gerada.
    • empirical: construiu o índice em memória sobre os grânulos remanescentes após o pruning de referência e contou os grânulos que o índice pularia. Este é um limite superior — veja as limitações em CREATE HYPOTHETICAL INDEX.
    • statistical: derivado de estatísticas de coluna. Usado quando a estimativa empírica está desabilitada (empirical = 0) ou não conseguiu produzir um resultado, e há estatísticas de coluna definidas nas colunas relevantes.
    • applicability_only: o índice é aplicável ao predicado, mas nem a estimativa empírica nem a estatística produziram um resultado (por exemplo, empirical = 0 e nenhuma estatística de coluna definida). Informa skip_ratio: 0.0% como um limite conservador.
  • sampled_parts / sampled_marks<baseline-pruned> / <total in the table>. Mostra que fração da tabela restou após o pruning por PK, partição e índices existentes, ou seja, a entrada para o índice hipotético.
  • est_bytes — uma estimativa dos bytes lidos, derivada do tamanho médio de linha da tabela; por isso, é aproximada e varia conforme o armazenamento e a compressão. A linha de referência aparece apenas quando a consulta lê linhas; a linha de cada candidato, apenas quando a estimativa de bytes da linha de referência é conhecida.
A configuração é escrita inline entre WHATIF e SELECT — não há palavra-chave SETTINGS (isso corresponde à forma como outras variantes de EXPLAIN aceitam suas opções). Se nenhum índice hipotético estiver definido para a tabela, EXPLAIN WHATIF informa status: not_applicable com uma dica para criar um. Linha combinada (múltiplos candidatos) Quando dois ou mais candidatos são avaliados empiricamente, EXPLAIN WHATIF acrescenta um bloco extra chamado (combined: idx_a, idx_b, ...) após as linhas de cada candidato. Ele informa o benefício conjunto de ter todos esses índices ao mesmo tempo: uma leitura real mantém um grânulo apenas se ele sobreviver a todos os skip indexes, portanto a estimativa combinada é a interseção dos grânulos sobreviventes dos candidatos. Seu skip_ratio é, portanto, pelo menos tão alto quanto o do melhor candidato individual — índices complementares fazem mais pruning em conjunto, enquanto índices redundantes o mantêm inalterado. Só contribuem os candidatos com source: empirical, porque a linha combinada é formada pela interseção dos conjuntos de sobrevivência por grânulo de cada um. Os candidatos estimados como statistical ou applicability_only não têm dados por grânulo e são excluídos; consequentemente, o bloco combinado aparece somente quando pelo menos dois candidatos produziram uma estimativa empírica, e é omitido caso contrário (por exemplo, com empirical = 0). Seus campos de estimativa são os mesmos de um bloco empírico por candidato, exceto que elapsed_us é 0 — a estimativa combinada é derivada das varreduras por candidato, não de uma nova varredura. O nome sintético (combined: ...) é apenas um rótulo do relatório e não pode ser usado com force_data_skipping_indices. Exemplo empírico
O minmax hipotético reduziria de 100 marcas para 1 — skip_ratio: 99.0%. (est_bytes é uma estimativa com base no tamanho médio da linha, portanto o valor exato varia.) Exemplo estatístico As estatísticas de coluna vêm desativadas por padrão. Para usar o caminho statistical, primeiro defina-as nas colunas relevantes e aguarde a conclusão da mutação de materialização:
Em seguida, desative o caminho empírico para que o estimador passe a usar as estatísticas de coluna:
O número vem da seletividade das estatísticas da coluna de b < 10 (cerca de 10 linhas em 10000) e é informado como um limite superior de skip_ratio. Não há sampled_parts / sampled_marks — nenhum dado foi lido. Se nenhum dos dois caminhos estiver disponível (por exemplo, empirical = 0 e nenhuma estatística de coluna definida), o estimador informa source: applicability_only e um skip_ratio: 0.0% conservador.

EXPLAIN TABLE OVERRIDE

Mostra o resultado de um override de tabela em um esquema acessado por meio de uma função de tabela. Também faz algumas validações, gerando uma exceção se o override causar algum tipo de falha. Exemplo Suponha que você tenha uma tabela MySQL remota como esta:
Query
Query
Response
A validação não está completa, portanto uma consulta bem-sucedida não garante que o override não cause problemas.
Última modificação em 23 de julho de 2026