Veo un rendimiento realmente extraño relacionado con una consulta muy simple usando Entity Framework Code-First con .NET Framework versión 4. La consulta LINQ2Entities se ve así:
context.MyTables.Where(m => m.SomeStringProp == stringVar);
Esto tarda más de 3000 milisegundos en ejecutarse. El SQL generado parece muy simple:
SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp],
...
FROM [MyTable] as [Extent1]
WHERE [Extent1].[SomeStringProp] = '1234567890'
Esta consulta se ejecuta casi instantáneamente cuando se ejecuta a través de Management Studio. Cuando cambio el código C # para usar la función SqlQuery, se ejecuta en 5-10 milisegundos:
context.MyTables.SqlQuery("SELECT [Extent1].[ID] ... WHERE [Extent1].[SomeStringProp] = @param", stringVar);
Entonces, exactamente el mismo SQL, las entidades resultantes tienen un seguimiento de cambios en ambos casos, pero hay una gran diferencia de rendimiento entre las dos. ¿Lo que da?
performance
entity-framework
ef-code-first
Brian Sullivan
fuente
fuente
Performance Considerations for Entity Framework 5
Respuestas:
Lo encontré. Resulta que es un problema de tipos de datos SQL. La
SomeStringProp
columna de la base de datos era un varchar, pero EF asume que los tipos de cadena .NET son nvarchars. El proceso de traducción resultante durante la consulta para que la base de datos haga la comparación es lo que lleva mucho tiempo. Creo que EF Prof me estaba desviando un poco aquí, una representación más precisa de la consulta que se está ejecutando sería la siguiente:Entonces, la solución resultante es anotar el modelo de código primero, indicando el tipo de datos SQL correcto:
fuente
varchar
para todo, y de hecho, este era el problema. Me pregunto si puedo hacer un EDMX para considerar varchar para todas las columnas de cadenas.La razón de ralentizar mis consultas realizadas en EF fue comparar escalares no anulables con escalares anulables:
Esa consulta tomó 35 segundos. Pero una pequeña refactorización como esa:
da resultados increíbles. Solo tardó 50 ms en completarse. Es posible que sea un error en EF.
fuente
Si está utilizando el mapeo fluido, puede usarlo
IsUnicode(false)
como parte de la configuración para obtener el mismo efecto:http://msdn.microsoft.com/en-us/data/jj591617.aspx#1.9
http://msdn.microsoft.com/en-us/library/gg696416%28v=vs.103%29.aspx
fuente
Tuve el mismo problema (la consulta es rápida cuando se ejecuta desde el administrador SQL) pero cuando se ejecuta desde EF, el tiempo de espera expira.
Resulta que la entidad (que se creó a partir de la vista) tenía claves de entidad incorrectas. Entonces, la entidad tenía filas duplicadas con las mismas claves, y supongo que tuvo que agrupar en el fondo.
fuente
También encontré esto con una consulta ef compleja. Una solución para mí que redujo una consulta ef de 6 segundos a la segunda consulta SQL que generó fue desactivar la carga diferida.
Para encontrar esta configuración (ef 6) vaya al archivo .edmx y busque en Propiedades -> Generación de código -> Carga diferida habilitada. Establecer en falso.
Gran mejora en el rendimiento para mí.
fuente
Yo tuve este problema también. Resulta que el culpable en mi caso fue el rastreo de parámetros de SQL-Server .
La primera pista de que mi problema se debió de hecho al rastreo de parámetros fue que ejecutar la consulta con "set arithabort off" o "set arithabort on" produjo tiempos de ejecución drásticamente diferentes en Management Studio. Esto se debe a que ADO.NET usa por defecto "establecer arithabort desactivado" y Management Studio por defecto "establecer arithabort activado". La caché del plan de consulta mantiene diferentes planes en función de este parámetro.
Inhabilité el almacenamiento en caché del plan de consulta para la consulta, con la solución que puede encontrar aquí .
fuente