Entity Framework - 10 Dicas para melhorar o desempenho de consultas LINQ


Quando usamos o Entity Framework estamos incluindo mais uma camada em nossa aplicação o que tem implicações no seu desempenho. Da mesma forma quando realizamos consultas em nosso modelo de entidades usando LINQ podemos também afetar o desempenho da nossa aplicação. Considerando essas implicações veremos como podemos melhorar o desempenho do Entity Framework em nosso projeto.

Dicas para melhorar o desempenho

1 - Evite colocar todos os objetos de banco de dados em um único modelo de entidade

O modelo de entidades especifica uma única unidade de trabalho, e não todo o nosso banco de dados. Se tivermos muitos objetos de banco de dados que não estão conectados ou (tabelas de log, objetos utilizados por processos em batch, etc) eles não serão usados. Assim, esses objetos estarão consumindo espaço na memória e degradando o desempenho. Portanto, tente fazer modelos de entidades separados de objetos de banco de dados relacionados.

2- Desative o controle de alterações (change tracking) para a entidade se isto não for necessário

Sempre que você recuperar os dados apenas para fins de leitura e não para a modificação, então não há necessidade de rastreamento de objetos. Então desabilite o controle de objetos usando MergeOption como abaixo:

NorthwindDataContext context = new NorthwindDataContext()
context.tblCities.MergeOption = MergeOption.NoTracking;

A Enumeração MergeOption especifica como os objetos que estão sendo carregados no contexto do objeto são mesclados com objetos já no contexto do objeto. Na opção NoTracking os objetos são mantidos em um estado Detached e não são rastreados no ObjectStateManager.

Esta opção permite desligar o cache de objetos e o gerenciamento de identidade de objetos desnecessário.

3 - Use Views geradas previamente para reduzir o tempo de resposta para a primeira solicitação

Quando o objeto de ObjectContext é criado pela primeira vez na aplicação, a estrutura de entidade cria um conjunto de classes que são necessárias para acessar o banco de dados. Este conjunto de classes é chamado view e se o seu modelo de dados é grande, então, criar a view pode atrasar a resposta da aplicação para o primeiro pedido de uma página. Podemos reduzir este tempo de resposta, criando uma view em tempo de compilação, usando modelo T4 ou a ferramenta EdmGen.exe de linha de comando.

4 - Evite retornar campos não obrigatórios do banco de dados.

Suponha que eu tenha uma tabela Clientes com 20 campos e estou interessado apenas em três campos - ClienteID, Nome, Endereco.

A recomendação e retornar apenas estes três campos, em vez de buscar todos os campos da tabela Cliente.

Retorna todos os campos da entidade Cliente:

var cliente = (from clit in contexto.Clientes select cli).ToList();

Retorna apenas os 3 campos desejados da entidade Cliente: (recomendado)

var cliente = (from cli in contexto.Clientes select new { cliente.ClienteID, cliente.Nome, cliente.Endereco}).ToList();

5 - Escolha a coleção apropridada para a manipulação de dados

Em LINQ podemos tratar a manipulação de dados usando a coleções Var, IEnumerable, IQueryable, IList. Cada coleção tem a sua importância e impacto no desempenho da consulta, portanto, cuidado ao escolher a coleção para manipulação de dados.

Veja a seguir algumas considerações sobre cada uma:

6 - Utilize consultas compiladas sempre que necessário

Realize consultas usando consultas compiladas se a consulta for freqüentemente usada para buscar os registros do banco de dados.A consulta será lenta na primeira vez, mas depois ela vai melhorar o desempenho de forma significativa. Para compilar uma consulta podemos usar o método Compile da classe CompiledQuery.

Assim para recuperar os detalhes dos clientes várias vezes baseado em um critério como a cidade podemos fazer essa consulta compilada da seguinte forma:

- Consulta simples (não compilada)
IQueryable lstCli = from cliente in mobjentity.tblClientes where cliente.Cidade == "Lins" select cliente;

- Consulta Compilada
Func> compiledQuery
= CompiledQuery.Compile>((ctx, cidade) =>from cliente in ctx.Clientes where cliente.Cidade == cidade select cliente);

7 - Retorne somente o número de registros requeridos na paginação

Quando estamos vinculando dados a um grid para fazer a paginação, retornar somente os registros requeridos melhora o desempenho. Isso pode conseguido usando os métodos Take, While e Skip.

NorthwindEntities mobjentity = new NorthwindEntities();
int pageSize = 10, startingPageIndex = 2;

List lstCli = mobjentity.tblClientes.Take(pageSize).Skip(startingPageIndex * pageSize).ToList();

8 - Evite usar o método Contains

O método Contains determina se uma seqüência contém um elemento especificado.

Quando usamos o método Contains em uma consulta LINQ ele é convertido para "WHERE IN" no SQL e isto afeta o desempenho.

9- Evita utilizar Views

As Views degradam o desempenho da consulta LINQ. Elas são lentas e impactam o desempenho consideravelmente. Evite-as.

10 - Debug e otimize as consultas LINQ (LINQPad)

Depurar e otimizar uma consulta LINQ é recomendado e para fazer isso o LINQ Pad é uma grande ferramenta. Com ela você pode criar, depurar e otimizar consultas LINQ facilmente.

João 6:65 E continuou: Por isso vos disse que ninguém pode vir a mim, se pelo Pai lhe não for concedido.

João 6:66 Por causa disso muitos dos seus discípulos voltaram para trás e não andaram mais com ele.

João 6:67 Perguntou então Jesus aos doze: Quereis vós também retirar-vos?

Referências:


José Carlos Macoratti