M365Con 2027 – conferência online gratuita · 11–22 Jan 2027 · 120 sessions→ m365con.net

Blog · Mirko Peters

Resolvendo o problema de N+1 consultas de uma vez por todas

By ·

Bem-vindos de volta, colegas desenvolvedores! Se você já criou uma aplicação usando o Entity Framework Core, é bem provável que tenha esbarrado em gargalos de desempenho que o deixaram coçando a cabeça. Por que uma consulta que roda instantaneamente no ambiente de desenvolvimento se arrasta em produção? Muitas vezes, o culpado está escondido bem à vista: o famigerado problema de N+1 consultas. Nes

Automatically translated with AI from the original post. Read the English original

▶ BLOGConquering the N+1 QueryProblem Once and For AllM365.FM
Titelbild: Conquering the N+1 Query Problem Once and For All

Bem-vindos de volta, colegas desenvolvedores! Se você já criou uma aplicação usando o Entity Framework Core, é bem provável que tenha esbarrado em gargalos de desempenho que o deixaram coçando a cabeça. Por que uma consulta que roda instantaneamente no ambiente de desenvolvimento se arrasta em produção? Muitas vezes, o culpado está escondido bem à vista: o famigerado problema de N+1 consultas. Neste post, vamos analisar a fundo o que causa esse assassino silencioso de desempenho, como você pode detectá-lo antes que seus usuários percebam e como corrigi-lo com eficácia usando carregamento adiantado (eager loading), projeções e técnicas inteligentes de otimização.

Antes de entrarmos nos detalhes técnicos, não deixe de conferir o episódio de podcast relacionado: Improve Entity Framework Core Query Performance. Nesse episódio, detalhamos várias armadilhas comuns do Entity Framework e compartilhamos orientações práticas para manter suas aplicações rodando com muita velocidade.

Entendendo o problema de N+1 consultas

O que é o N+1?

O problema de N+1 acontece quando você carrega dados relacionados de um jeito que gera muitas consultas extras. No Entity Framework Core, isso costuma aparecer quando você acessa dados relacionados dentro de um loop. Por exemplo, você pode buscar 100 pedidos. Depois, para cada pedido, você acessa a propriedade do cliente. Isso dispara uma consulta para todos os pedidos e mais 100 consultas, uma para cada cliente. No fim, você tem 101 consultas em vez de apenas uma. Isso deixa sua aplicação mais lenta, principalmente quando há muitos dados. Com conjuntos de dados pequenos, você pode não perceber o problema, mas ele se torna grave em produção.

Detectando consultas N+1 em produção

Você pode identificar o problema de N+1 observando quantas consultas sua aplicação envia ao banco de dados. Veja algumas formas de detectá-lo:

  • Ative o log de SQL para ver cada consulta executada.
  • Use ferramentas de profiling para verificar o desempenho das consultas.
  • Monitore a quantidade de consultas. Se você vir muitas consultas para um resultado pequeno, pode ter um problema de N+1.
  • Teste sua aplicação com grandes conjuntos de dados, semelhantes aos que você usa em produção.

Dica: sempre verifique seus logs e ferramentas de profiling depois de adicionar novas consultas ou de alterar a forma como você carrega dados relacionados.

Corrigindo N+1 com eager loading

Você pode corrigir o problema de N+1 no Entity Framework Core usando eager loading. O eager loading permite buscar todos os dados de que você precisa em uma única consulta. Para isso, use o método Include. Ele instrui o EF a fazer join com as tabelas relacionadas e trazer tudo de uma vez. Por exemplo, se você quiser obter autores e seus livros, pode escrever:

var authorsWithBooks = context.Authors.Include(a => a.Books).ToList();

Esse código executa uma única consulta que faz join entre autores e livros. Sua aplicação recebe todos os dados de uma só vez. O eager loading reduz o número de consultas e torna sua aplicação mais rápida. Use eager loading quando souber que precisará dos dados relacionados imediatamente. Isso ajuda a evitar lentidão e mantém sua aplicação funcionando sem problemas.

Rastreamento versus sem rastreamento para desempenho

O Entity Framework Core rastreia cada entidade que você carrega. Esse é o comportamento padrão. O rastreamento ajuda o EF a saber se você alterou algo. Mas ele pode deixar sua aplicação mais lenta. É mais lento com grandes conjuntos de dados. Sua aplicação pode passar a consumir mais memória. As consultas também podem demorar mais quando o rastreamento está ativo. Usar AsNoTracking torna as consultas mais rápidas. Também consome menos memória. Sua aplicação responde mais rápido e consegue atender mais usuários ao mesmo tempo.

Dica: se você desativar o rastreamento, suas consultas rodam mais rápido. Isso é ideal quando você só precisa ler dados.

Use AsNoTracking se você não quiser atualizar ou excluir os dados. A maioria das APIs web apenas lê dados. Cerca de 70 a 80% dos endpoints apenas exibem informações. Esses funcionam melhor com AsNoTracking. Aqui estão alguns bons momentos para usá-lo:

  • Relatórios e painéis que apenas exibem dados
  • Respostas de API que retornam listas ou detalhes para exibição
  • Endpoints de busca ou filtro que apenas leem do banco de dados

Paginação e grandes conjuntos de dados

Quando você usa o EF com muitos dados, pode enfrentar grandes problemas. Carregar dados demais de uma vez pode deixar sua aplicação lenta ou até fazê-la travar. Veja algumas coisas que podem acontecer:

  • Sua aplicação pode consumir memória demais e ficar sem ela.
  • Pode levar muito tempo para obter respostas porque há dados demais.
  • O banco de dados pode parar de funcionar se você tentar carregar muita informação de uma vez.

Você pode resolver esses problemas usando paginação. A paginação divide seus dados em partes menores. Isso deixa sua aplicação mais rápida e fácil de usar. No EF, você pode usar Skip() e Take() para fazer isso. O Skip permite pular alguns registros. O Take obtém apenas a quantidade que você deseja. Isso ajuda a trabalhar com grandes volumes de dados e mantém sua aplicação funcionando bem.

Operações em massa e agrupamento de lotes

Você pode tornar o seu banco de dados mais rápido com operações em massa. Esses métodos permitem alterar muitos registros ao mesmo tempo. Os métodos padrão do EF são adequados para tarefas pequenas, mas ficam lentos quando há muitos dados. Operações em massa ajudam a inserir, atualizar ou excluir milhares de linhas com rapidez. Você pode usá-las ao importar dados de arquivos CSV. Elas também ajudam na sincronização de registros ou em atualizações noturnas.

O agrupamento em lotes permite agrupar ações para que sua aplicação funcione mais rápido. Você pode usar atualizações em lote com UpdateRange() para alterar muitos itens de uma só vez. Evite chamar SaveChanges() com muita frequência, pois cada chamada envia dados ao banco de dados. O EF Core 7 introduz novos métodos, como ExecuteUpdate e ExecuteDelete, para alterações em massa.

Conclusão

Otimizar o Entity Framework Core não precisa ser um exercício de adivinhação. Ao entender como ocorre o problema de consultas N+1, usar ferramentas para monitorar o SQL gerado, aplicar carregamento antecipado (eager loading) e consultas sem rastreamento, além de incorporar paginação e operações em massa, você pode transformar uma camada de dados lenta em um mecanismo de alto desempenho. Sempre meça sua linha de base de desempenho e teste suas consultas com rigor em condições realistas.

Para se aprofundar ainda mais nessas estratégias, não deixe de ouvir o episódio complementar em Improve Entity Framework Core Query Performance. Aplicar essas boas práticas vai proteger suas aplicações de gargalos ocultos e garantir uma experiência fluida para os seus usuários!

Entities in this article

Entity Framework Core

RSS