Estou vendo um desempenho realmente estranho relacionado a uma consulta muito simples usando o Entity Framework Code-First com .NET framework versão 4. A consulta LINQ2Entities se parece com isto:
context.MyTables.Where(m => m.SomeStringProp == stringVar);
Isso leva mais de 3.000 milissegundos para ser executado. O SQL gerado parece muito simples:
SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp],
...
FROM [MyTable] as [Extent1]
WHERE [Extent1].[SomeStringProp] = '1234567890'
Essa consulta é executada quase instantaneamente quando executada por meio do Management Studio. Quando eu altero o código C # para usar a função SqlQuery, ele é executado em 5 a 10 milissegundos:
context.MyTables.SqlQuery("SELECT [Extent1].[ID] ... WHERE [Extent1].[SomeStringProp] = @param", stringVar);
Portanto, exatamente o mesmo SQL, as entidades resultantes são rastreadas por alterações em ambos os casos, mas uma grande diferença de desempenho entre os dois. O que da?
performance
entity-framework
ef-code-first
Brian Sullivan
fonte
fonte
Performance Considerations for Entity Framework 5
Respostas:
Encontrei. Acontece que é um problema de tipos de dados SQL. A
SomeStringProp
coluna no banco de dados era um varchar, mas EF assume que os tipos de string .NET são nvarchars. O processo de tradução resultante durante a consulta para o banco de dados fazer a comparação é o que leva muito tempo. Acho que o EF Prof estava me enganando um pouco aqui, uma representação mais precisa da consulta que está sendo executada seria a seguinte:Portanto, a correção resultante é anotar o modelo de código, indicando o tipo de dados SQL correto:
fonte
varchar
para tudo, e de fato esse era o problema. Gostaria de saber se posso fazer um EDMX para considerar varchar para tudo coluna de string.O motivo de desacelerar minhas consultas feitas no EF foi comparar escalares não anuláveis com escalares anuláveis:
Essa consulta demorou 35 segundos. Mas uma pequena refatoração como essa:
dá resultados incríveis. Demorou apenas 50 ms para ser concluído. É possível que seja um bug no EF.
fonte
Se estiver usando o mapeamento fluente, você pode usar
IsUnicode(false)
como parte da configuração para obter o mesmo efeito -http://msdn.microsoft.com/en-us/data/jj591617.aspx#1.9
http://msdn.microsoft.com/en-us/library/gg696416%28v=vs.103%29.aspx
fonte
Tive o mesmo problema (a consulta é rápida quando executada do gerenciador de SQL) mas quando executada do EF o tempo limite expira.
Acontece que a entidade (que foi criada a partir da visualização) tinha chaves de entidade erradas. Portanto, a entidade tinha linhas duplicadas com as mesmas chaves e acho que tinha que fazer o agrupamento no fundo.
fonte
Eu também me deparei com isso com uma consulta ef complexa. Uma correção para mim que reduziu uma consulta ef de 6 segundos para a consulta sql sub-segundo que gerou foi desligar o carregamento lento.
Para encontrar esta configuração (ef 6) vá para o arquivo .edmx e procure em Propriedades -> Geração de código -> Carregamento lento ativado. Defina como falso.
Melhoria maciça de desempenho para mim.
fonte
Eu tive esse problema também. Acontece que o culpado no meu caso foi a detecção de parâmetros do SQL Server .
A primeira pista de que meu problema era na verdade devido à detecção de parâmetro era que executar a consulta com "set arithabort off" ou "set arithabort on" gerava tempos de execução drasticamente diferentes no Management Studio. Isso ocorre porque o ADO.NET por padrão usa "set arithabort off" e o Management Studio usa como padrão "set arithabort on". O cache do plano de consulta mantém planos diferentes dependendo deste parâmetro.
Desativei o cache do plano de consulta para a consulta, com a solução que você encontra aqui .
fonte