63 votos

Entity Framework es demasiado lento. ¿Cuáles son mis opciones?

He seguido el "no Optimizar Prematuramente" mantra y codificado mi Servicio WCF utilizando Entity Framework.

Sin embargo, perfila el rendimiento y Entity Framework es demasiado lento. (Mi aplicación de procesos 2 mensajes en alrededor de 1,2 segundos, donde el (legado) de la aplicación que estoy re-escritura de hace 5-6 mensajes en el mismo tiempo. (El legado de la aplicación de las llamadas sprocs para su base de datos de Acceso.)

Mi generación de perfiles de puntos de la Entidad Marco de tomar la mayor parte del tiempo por mensaje.

Así que, ¿cuáles son mis opciones?

  • ¿Hay mejor Orm?
    (Algo que sólo apoya normal de la lectura y la escritura de los objetos y lo hace rápido..)

  • Es allí una manera de hacer Entity Framework más rápido?
    (Nota: cuando digo más rápido me refiero a que en el largo plazo, no es la primera llamada. (La primera llamada es lento (15 segundos de un mensaje), pero que no es un problema. Sólo tengo que ser rápido para que el resto de los mensajes.)

  • Algún misterioso 3ª opción que me ayudará a conseguir más velocidad de mi servicio.

NOTA: la Mayoría de los de mi DB interacciones o Crear y Actualizar. Me hacen muy muy poco de seleccionar y eliminar.

33voto

Sean Puntos 311

El hecho del asunto es que los productos tales como Entity Framework SIEMPRE será lento e ineficiente, porque se ejecutan mucho más código.

También me parece tonto que la gente se lo que sugiere que uno debe optimizar las consultas de LINQ, mira el SQL generado, el uso de depuradores, pre-compilar, tomar muchas medidas, etc. es decir, perder un montón de tiempo. Nadie dice: - Simplificar! Todo el mundo quiere comlicate cosas más por tomar aún más medidas (perdiendo el tiempo).

Un enfoque de sentido común sería no utilizar EF o LINQ. Utilizar texto SQL. No hay nada de malo con ello. Simplemente porque no hay mentalidad de rebaño entre los programadores y sienta la necesidad de utilizar cada nuevo producto que hay, no significa que es bueno o va a trabajar. La mayoría de los programadores piensan que si se incorporan cada nueva pieza de código publicado por una gran empresa, se está haciendo de una forma más inteligente programador; no es cierto en absoluto. Programación inteligente es principalmente acerca de cómo hacer más con menos dolores de cabeza, incertidumbres, y en la menor cantidad de tiempo. Recuerde - El Tiempo! Que es el elemento más importante, así que trate de encontrar maneras de no perder en la solución de problemas en las malas/hinchado código escrito simplemente para cumplir con algunos extraños llamados "patrones"

Relajarse, disfrutar de la vida, tomar un descanso de la codificación y la deje de usar las características adicionales, el código, los productos, los 'patrones'. La vida es corta y la vida de su código es más corto, y ciertamente no es ciencia de cohetes. Eliminar capas como LINQ, EF y otros, y su código se ejecute de manera eficiente, escala, y sí, es fácil de mantener. Demasiada abstracción es una mala 'patrón'.

Y esa es la solución a su problema.

29voto

J. Tihon Puntos 3519

Usted debe comenzar por los perfiles de los comandos SQL en realidad emitido por el Marco de la Entidad. Dependiendo de su configuración (a POCO, las entidades Self-Tracking) no hay mucho espacio para las optimizaciones. Puede depurar los comandos SQL (que no difieren entre debug y release mode) el uso de la ObjectSet<T>.ToTraceString() método. Si encuentro una consulta que requiere de una mayor optimización puede utilizar algunas proyecciones para dar EF obtener más información acerca de lo que estás tratando de lograr.

Ejemplo:

Product product = db.Products.SingleOrDefault(p => p.Id == 10);
// executes SELECT * FROM Products WHERE Id = 10

ProductDto dto = new ProductDto();
foreach (Category category in product.Categories)
// executes SELECT * FROM Categories WHERE ProductId = 10
{
    dto.Categories.Add(new CategoryDto { Name = category.Name });
}

Podría ser sustituida por:

var query = from p in db.Products
            where p.Id == 10
            select new
            {
                p.Name,
                Categories = from c in p.Categories select c.Name
            };
ProductDto dto = new ProductDto();
foreach (var categoryName in query.Single().Categories)
// Executes SELECT p.Id, c.Name FROM Products as p, Categories as c WHERE p.Id = 10 AND p.Id = c.ProductId
{
    dto.Categories.Add(new CategoryDto { Name = categoryName });
}

Me acaba de escribir que fuera de mi cabeza, así que esto no es exactamente cómo iba a ser ejecutado, pero EF hace agradable optimizaciones si le dices que todo lo que usted sabe acerca de la consulta (en este caso, que vamos a necesitar a la categoría de nombres). Pero esto no es como con ganas de carga (db.Productos.Include("Categorías")) debido a que las proyecciones pueden reducir aún más la cantidad de datos a cargar.

26voto

Steve Wortham Puntos 11563

Una sugerencia es usar LINQ to Entity Framework sólo para el registro único de CRUD declaraciones.

Para obtener más involucrados consultas, búsquedas, informes, etc, escribir un procedimiento almacenado y agregar a la modelo de Entity Framework, como se describe en MSDN.

Este es el enfoque que he tomado con un par de mis sitios y parece ser un buen compromiso entre rendimiento y productividad. Entity Framework no siempre generan la mayoría de SQL eficaz para la tarea a mano. Y en vez de pasar el tiempo para averiguar por qué, escribir un procedimiento almacenado para las consultas más complejas realmente ahorra tiempo para mí. Una vez que lo haya hecho, no es demasiado de un molestia para agregar procedimientos almacenados para su modelo de EF. Y, por supuesto, el beneficio de añadir que su modelo es que usted consigue todo lo que inflexible de la bondad que viene de usar un ORM.

11voto

JulianR Puntos 7257

Si usted es puramente obtención de datos, es una gran ayuda para el rendimiento cuando le dices a EF para no seguir la pista de las entidades a que se recupera. Hacer esto mediante el uso de MergeOption.NoTracking. EF se acaba de generar la consulta, ejecutar y deserializar los resultados a los objetos, pero no el intento de mantener un seguimiento de los cambios de la entidad o cualquier cosa de esa naturaleza. Si una consulta es simple (no pasar mucho tiempo de espera en la base de datos a cambio), he descubierto que el establecimiento a NoTracking puede duplicar el rendimiento de la consulta.

Consulte este artículo de MSDN en la MergeOption enumeración:

La identidad de la Resolución, la Administración de Estado, y el Seguimiento de Cambios

Este parece ser un buen artículo sobre EF rendimiento:

El rendimiento y el Marco de la Entidad

3voto

Sean Kearon Puntos 2670

Usted dice que usted tiene un perfil de la aplicación. Ha perfilado el ORM? Hay una EF que el analizador de Ayende que destacará donde usted puede optimizar su EF código. Usted puede encontrar aquí:

http://efprof.com/

Recuerde que usted puede utilizar SQL tradicional enfoque junto a su ORM si usted necesita para obtener el rendimiento.

Si hay un más rápido/mejor ORM? Dependiendo de su objeto/modelo de datos, usted podría considerar el uso de uno de los micro-Orm, tales como Dapper, Masiva o PetaPoco.

El Apuesto sitio publica algunos comparativo puntos de referencia que le dará una idea de cómo se comparan con otras Orm. Pero vale la pena señalar que el micro-Orm no apoyo el rico conjunto de características de la plena Orm como EF y NH.

Puede que desee echar un vistazo a RavenDB. Esta es una base de datos no relacional (de Ayende de nuevo) que te permite almacenar POCOs directamente con ninguna asignación necesario. RavenDB está optimizado para las lecturas y hace que los desarrolladores de la vida mucho más fácil mediante la eliminación de la necesidad de manipular el esquema y mapa de sus objetos, a ese esquema. Sin embargo, ser conscientes de que esto es muy diferente enfoque para el uso de un ORM enfoque y estos se detallan en el producto sitio.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X