Lendo um plano EXPLAIN
Interpretando tipos de varredura, métodos de junção e estimativas de custo em um plano de consulta.
Lendo um plano EXPLAIN é uma aula grátis de Coding Interview Prep no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Coding Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Coding Interview Prep inclui 4 aulas no total.
Por que os entrevistadores perguntam sobre EXPLAIN
Quando você chega a uma entrevista para uma vaga sênior, os entrevistadores deixam de perguntar escreva uma consulta e passam a perguntar por que esta consulta está lenta. A ferramenta que responde a isso é EXPLAIN.
EXPLAIN mostra o plano de execução do banco de dados: a estratégia passo a passo que o planejador escolheu para executar seu SQL. Ele revela quais tabelas são percorridas, em que ordem elas são associadas e aproximadamente quanto custa cada etapa.
Saber ler um plano demonstra que você entende o mecanismo, não apenas a sintaxe. É exatamente o critério que os entrevistadores usam para diferenciar um profissional de nível intermediário de um profissional sênior.
EXPLAIN versus EXPLAIN ANALYZE
Há duas formas, e os entrevistadores adoram essa distinção.
- EXPLAIN mostra o plano estimado pelo planejador sem executar a consulta. É rápido e seguro.
- EXPLAIN ANALYZE realmente executa a consulta e informa as quantidades reais de linhas e os tempos de execução, juntamente com as estimativas.
O ponto mais valioso é comparar as linhas estimadas com as linhas reais. Uma grande discrepância significa que o planejador tem estatísticas ruins e provavelmente está tomando uma decisão inadequada.
Atenção: EXPLAIN ANALYZE executa a consulta de verdade, portanto realizará qualquer INSERT ou UPDATE, a menos que esteja dentro de uma transação revertida.
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;Como ler a árvore
Um plano é uma árvore, não uma lista. Os nós mais recuados são as folhas, que são executadas primeiro; os resultados sobem até a raiz, que produz a saída final.
Leia de dentro para fora: encontre o nó mais profundo; é ali que a execução começa. Cada nó pai consome as linhas emitidas pelos seus filhos.
Em uma entrevista, explique dessa forma: primeiro percorremos esta tabela, essas linhas alimentam esta junção, a junção alimenta a ordenação e a ordenação alimenta o limite. É essa explicação de baixo para cima que eles querem ouvir.
Anatomia de um nó de plano
Cada nó em um plano do Postgres contém os mesmos números principais:
- custo=0.00..35.50 custo de inicialização..custo total em unidades arbitrárias do planejador
- linhas=1000 número estimado de linhas produzidas
- largura=64 tamanho médio estimado de uma linha em bytes
O primeiro custo é o custo de inicialização (trabalho realizado antes de a primeira linha aparecer, como criar uma tabela hash). O segundo é o custo total para retornar todas as linhas. Um custo total maior é a estimativa do planejador de uma despesa relativa maior.
Seq Scan on orders (cost=0.00..35.50 rows=1000 width=64)Um exemplo detalhado
Considere uma consulta simples com filtro. O plano abaixo conta uma história em uma única linha.
É uma varredura sequencial (leitura completa da tabela) em orders, aplicando o filtro status = 'shipped'. O planejador estima 1000 linhas correspondentes.
Se orders tiver 10 milhões de linhas e apenas 1000 corresponderem, espera-se que, em uma entrevista, o candidato diga: uma varredura sequencial aqui é desperdício; um índice em status (ou em uma coluna mais seletiva) permitiria evitar a leitura da tabela inteira.
EXPLAIN SELECT * FROM orders WHERE status = 'shipped';
Seq Scan on orders (cost=0.00..18334.00 rows=1000 width=64)
Filter: (status = 'shipped'::text)Linhas estimadas e reais
Com EXPLAIN ANALYZE, você também obtém números reais entre parênteses.
Observe o exemplo: o planejador estimou 1000 linhas, mas obteve de fato 480000. Isso representa uma subestimativa de 480 vezes. O planejador escolheu sua estratégia supondo poucas linhas, portanto sua escolha provavelmente está errada para os dados reais.
Em entrevistas, essa diferença é o seu diagnóstico principal: as estatísticas estão desatualizadas; execute ANALYZE na tabela e, então, o planejador provavelmente escolherá um plano melhor.
Seq Scan on orders
(cost=0.00..18334.00 rows=1000 width=64)
(actual time=0.02..210.4 rows=480000 loops=1)O que significa iterações=N
O valor de loops é mais importante do que os candidatos esperam. Ele representa o número de vezes que um nó foi executado.
Isso aparece no lado interno de uma junção com laço aninhado: o nó interno é executado uma vez para cada linha externa. Se loops=480000, essa etapa interna foi executada 480 mil vezes.
Importante: o tempo por linha e a quantidade de linhas exibidos são por iteração. Para obter o total verdadeiro, multiplique esses valores por loops. Um nó que parece barato, custando 0.004ms por iteração, passa a custar quase 2 segundos ao longo de 480000 iterações.
Index Scan using idx_cust on orders
(actual time=0.003..0.004 rows=1 loops=480000)O custo é relativo, não é medido em milissegundos
Uma armadilha frequente: candidatos leem cost=18334 e dizem isso leva 18 segundos. Errado.
O custo é expresso em unidades arbitrárias do planejador, calibradas de modo que uma leitura sequencial de página seja igual a 1.0. Ele só é significativo para comparar planos entre si, não como uma medida de tempo real.
Para obter o tempo real, você precisa de EXPLAIN ANALYZE e dos valores de actual time, medidos em milissegundos. Diga isso claramente em uma entrevista; isso demonstra que você realmente entende a métrica.
Lendo um plano de junção
Aqui está um plano envolvendo duas tabelas. Leia-o de baixo para cima.
As duas primeiras varreduras coletam linhas de orders e customers. Elas alimentam uma junção por hash: um lado é transformado em uma tabela hash, e o outro consulta essa tabela. A saída da junção alimenta então o resultado final.
Observe que a indentação mostra a estrutura: as duas varreduras estão abaixo da junção por hash. O entrevistador quer que você identifique o método de junção (hash, neste caso) e qual tabela está sendo transformada em hash (geralmente a menor).
Hash Join (cost=30.0..520.0 rows=900 width=72)
Hash Cond: (o.customer_id = c.id)
-> Seq Scan on orders o (cost=0..400 rows=10000)
-> Hash (cost=18..18 rows=500)
-> Seq Scan on customers c (cost=0..18 rows=500)Sinais de alerta a destacar
Treine seu olhar para identificar estes sinais de alerta em qualquer plano:
- Varredura sequencial em uma tabela enorme com um filtro seletivo; um índice poderia ajudar.
- Linhas estimadas muito diferentes das reais, indicando estatísticas desatualizadas.
- Laço aninhado com muitas iterações sobre uma tabela grande; geralmente falta um índice na chave da junção interna.
- Ordenação ou hash sendo gravado no disco (exibido como uso de
Disk);work_memé pequeno demais. - Linhas removidas pelo filtro em quantidade muito alta; a maior parte da tabela foi lida e descartada.
Formatos de saída e BUFFERS
Os planos podem estar em vários formatos. O padrão TEXT é o que você lê em voz alta nas entrevistas. Mas também é possível solicitar uma saída estruturada.
EXPLAIN (FORMAT JSON) ou FORMAT YAML produz planos legíveis por máquina, que ferramentas e painéis analisam. Raramente é necessário examiná-los manualmente, mas saber que eles existem é um detalhe que demonstra experiência.
Adicione opções entre parênteses: EXPLAIN (ANALYZE, BUFFERS). A opção BUFFERS informa os acertos no cache em comparação com as leituras do disco, o que é excelente para diagnosticar consultas limitadas pela E/S.
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = 42;Verificação rápida
Um entrevistador mostra a você um nó de EXPLAIN ANALYZE com rows=1000 na seção de custos, mas com actual ... rows=480000. Qual é o diagnóstico mais provável?
Recapitulação
Agora você já consegue ler um plano como uma pessoa experiente:
EXPLAINfaz estimativas;EXPLAIN ANALYZEexecuta e mede.- Leia a árvore de baixo para cima; as folhas são executadas primeiro, e a raiz produz a saída.
- Cada nó exibe custo (unidades relativas), linhas e largura;
actual timeé o valor real em milissegundos. loopsmultiplica os números por iteração; fique atento aos laços aninhados.- A diferença entre o número estimado e o número real de linhas é o seu principal sinal para diagnóstico.
Narre o plano em voz alta e destaque os sinais de alerta; esse é o comportamento que garante sucesso na entrevista.
Perguntas Frequentes
A aula “Lendo um plano EXPLAIN” é grátis?
Sim — o texto completo de “Lendo um plano EXPLAIN” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Coding Interview Prep, atualize para CoddyKit PRO. O curso de Coding Interview Prep inclui 4 aulas no total.
O que vou aprender em “Lendo um plano EXPLAIN”?
Interpretando tipos de varredura, métodos de junção e estimativas de custo em um plano de consulta. Você pratica Coding Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Coding Interview Prep?
Nenhuma experiência prévia é necessária. Coding Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Lendo um plano EXPLAIN”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Coding Interview Prep?
Sim. Cada aula de Coding Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Lendo um plano EXPLAIN
- Varredura sequencial, de índice e somente de índice
- Algoritmos de junção: loop aninhado, hash e mesclagem
- Identificando e corrigindo consultas lentas