Identificando e corrigindo consultas lentas
Uma lista de verificação diagnóstica para a pergunta de entrevista “esta consulta está lenta; corrija-a”.
Identificando e corrigindo consultas lentas é uma aula grátis de Coding Interview Prep no CoddyKit. Esta é a aula 4 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.
O enunciado «Esta consulta está lenta, corrija-a»
Este é o enunciado final da entrevista: o entrevistador entrega uma consulta lenta e um plano EXPLAIN ANALYZE e pede que você faça o diagnóstico. Ele está avaliando um método, não truques decorados.
Uma resposta forte segue uma lista de verificação em voz alta: medir, ler o plano, encontrar o custo dominante, formular uma hipótese, propor uma correção e verificar. Esta lição desenvolve essa lista passo a passo.
Seja sistemático e narre seu raciocínio; é isso que garante a avaliação de nível sênior.
Etapa 1: medir com EXPLAIN ANALYZE
Nunca adivinhe apenas com base na consulta. Obtenha o plano real com EXPLAIN (ANALYZE, BUFFERS).
ANALYZE fornece os tempos e as quantidades de linhas reais; BUFFERS mostra se você está obtendo dados da memória ou lendo do disco. Juntos, eles informam se a consulta é limitada pela CPU, pelas operações de entrada e saída ou se simplesmente está fazendo trabalho demais.
Execute-a algumas vezes; a primeira execução pode sofrer uma penalidade por não haver dados na memória, distorcendo o tempo medido.
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.created_at >= '2026-01-01';Etapa 2: encontrar o nó dominante
Não leia de cima para baixo procurando aleatoriamente. Encontre o nó em que o maior tempo é realmente gasto.
Calcule o tempo próprio de cada nó: seu actual time total menos o tempo de seus filhos, multiplicado por loops. O nó com a maior parcela é o seu alvo; todo o restante é ruído.
Nas entrevistas, diga: 80 por cento do tempo de execução está nesta única varredura sequencial, então é nela que vou me concentrar. Otimizar qualquer outra coisa seria esforço desperdiçado.
Etapa 3: verificar o estimado versus o real
No nó dominante, compare a quantidade estimada de linhas com a quantidade real. Uma grande diferença significa que o planejador está operando às cegas e provavelmente escolheu um plano ruim (algoritmo de junção incorreto, método de acesso incorreto).
O exemplo mostra uma subestimativa de 1000 vezes. Antes de reprojetar qualquer coisa, atualize as estatísticas; esse único comando frequentemente corrige o plano sem custo.
ANALYZE recalcula as estatísticas das colunas; VACUUM ANALYZE também limpa as tuplas obsoletas e atualiza o mapa de visibilidade.
-- estimate rows=100, actual rows=120000 -> stale stats
ANALYZE orders;
-- or, for bloated tables:
VACUUM ANALYZE orders;Causa comum: função em uma coluna indexada
O erro corrigível mais frequente: uma função ou conversão envolve a coluna em WHERE, impedindo o uso do índice e fazendo o mecanismo executar uma varredura sequencial.
O exemplo força uma varredura completa porque DATE() é aplicada a cada linha. Reescreva-a como um predicado de intervalo sobre a coluna sem função (forma sargável), e o índice em created_at passará a ser usado.
A mesma ideia vale para WHERE lower(email)=...: armazene os dados normalizados, consulte a coluna sem função ou crie um índice de expressão.
-- Not sargable: index unusable
WHERE DATE(created_at) = '2026-01-01'
-- Sargable: range over the bare column
WHERE created_at >= '2026-01-01'
AND created_at < '2026-01-02'Causa comum: índice ausente
Se o nó dominante for uma varredura sequencial com um filtro altamente seletivo, ou um laço aninhado com loops enorme sobre uma chave interna sem índice, a correção geralmente é criar um índice.
Adicione um índice à coluna filtrada ou unida. O exemplo cria um em customer_id para que a junção possa trocar as varreduras sequenciais por varreduras usando índice, e o planejador talvez escolha um plano muito mais barato.
Verifique executando novamente EXPLAIN ANALYZE; não presuma que o índice ajudou.
CREATE INDEX idx_orders_customer
ON orders (customer_id);Causa comum: SELECT * e linhas largas
SELECT * carrega todas as colunas do disco e pela rede, além de impedir varreduras somente pelo índice, pois o índice raramente contém todas as colunas.
Selecione apenas as colunas de que precisa. Isso reduz a largura das linhas, diminui a entrada e saída e pode permitir uma varredura somente por um índice de cobertura.
Um entrevistador que inclui SELECT * quer que você perceba isso. Reduzir a lista de colunas costuma gerar um ganho rápido e real em tabelas largas.
-- Before
SELECT * FROM orders WHERE customer_id = 42;
-- After: only needed columns (may enable index-only scan)
SELECT order_id, amount FROM orders WHERE customer_id = 42;Causa comum: transbordamento para o disco
Se um nó Sort ou Hash informar uso de disco (Sort Method: external merge Disk: 25000kB ou Batches: > 1), a operação excedeu work_mem e transbordou para o disco.
Opções: aumente work_mem para a sessão, reduza a quantidade de linhas que chega à ordenação ou à dispersão filtrando mais cedo, ou adicione um índice que forneça a ordem desejada para que nenhuma ordenação seja necessária.
Esse é um diagnóstico preciso, de nível sênior, que os entrevistadores valorizam.
Sort (actual rows=2000000 loops=1)
Sort Key: o.amount
Sort Method: external merge Disk: 25000kBCausa comum: busca de linhas em excesso
Observe Rows Removed by Filter: 9500000. A consulta leu dez milhões de linhas e descartou quase todas; é um desperdício clássico de trabalho.
Correções: adicione um índice para que o filtro seja aplicado durante o acesso, e não depois; torne o predicado mais seletivo; ou antecipe a filtragem na consulta para que menos linhas subam pela árvore.
O princípio é: faça o mínimo de trabalho, filtrando o mais cedo e da forma mais barata possível.
Seq Scan on events
Filter: (event_type = 'purchase')
Rows Removed by Filter: 9500000A lista de verificação diagnóstica
Recite isto na entrevista e você não perderá o rumo:
- Meça com
EXPLAIN (ANALYZE, BUFFERS). - Localize o nó que consome mais tempo.
- Compare as linhas estimadas e reais; corrija primeiro as estatísticas desatualizadas.
- Verifique a sargabilidade; remova as funções das colunas filtradas.
- Crie índices para filtros seletivos e chaves de junção.
- Reduza as colunas; evite
SELECT *. - Observe os transbordamentos para o disco e a busca de linhas em excesso.
- Verifique executando novamente o plano.
Juntando tudo
Explique em voz alta um exemplo completo. O plano mostra uma varredura sequencial em uma tabela orders com 50 milhões de linhas, filtro customer_id = 42, Rows Removed by Filter próximo de 50 milhões e uma estimativa aproximadamente compatível com o resultado real.
Diagnóstico: filtro seletivo, nenhum índice; o custo dominante é a varredura. Correção: CREATE INDEX ON orders(customer_id). Execute novamente: o plano muda para uma varredura por índice, e o tempo cai de segundos para menos de um milissegundo.
Esse ciclo de medir, diagnosticar, corrigir e verificar é o modelo de resposta para qualquer pergunta sobre uma consulta lenta.
CREATE INDEX idx_orders_customer ON orders (customer_id);
EXPLAIN (ANALYZE, BUFFERS)
SELECT order_id, amount FROM orders WHERE customer_id = 42;Verificação rápida
Uma consulta filtra com WHERE YEAR(order_date) = 2026, e o plano mostra uma varredura sequencial completa, apesar de existir um índice B-tree em order_date. Qual é a melhor primeira correção?
Recapitulação
Agora você tem um método repetível para responder a perguntas sobre consultas lentas:
- Sempre meça usando
EXPLAIN (ANALYZE, BUFFERS)e concentre-se no nó dominante. - Corrija primeiro as estatísticas desatualizadas quando as estimativas e os resultados reais divergirem.
- Torne os predicados sargáveis, adicione índices para filtros seletivos e chaves de junção, e elimine o uso de
SELECT *. - Resolva os derramamentos em disco e a busca excessiva de dados; depois, verifique o novo plano.
Descreva a lista de verificação, proponha uma mudança concreta e execute novamente o plano para comprová-la: essa é a resposta de nível sênior.
Perguntas Frequentes
A aula “Identificando e corrigindo consultas lentas” é grátis?
Sim — o texto completo de “Identificando e corrigindo consultas lentas” é 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 “Identificando e corrigindo consultas lentas”?
Uma lista de verificação diagnóstica para a pergunta de entrevista “esta consulta está lenta; corrija-a”. 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 4 de 4.
Quanto tempo leva a aula “Identificando e corrigindo consultas lentas”?
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