when stored procedimientos optimizar framework almacenados entity-framework stored-procedures performance-testing database-performance

entity-framework - procedimientos - stored procedure vs entity framework performance



Entity Framework Vs Stored Procedures-Performance Measurement (2)

Estoy tratando de establecer cuánto más lento es el marco de entidad en los procedimientos almacenados. Espero convencer a mi jefe para que nos permita usar Entity Framework para facilitar el desarrollo.

El problema es que realicé una prueba de rendimiento y parece que EF es aproximadamente 7 veces más lenta que los procesadores almacenados. Encuentro esto extremadamente difícil de creer, y me pregunto si me estoy perdiendo algo. ¿Es esto una prueba concluyente? ¿Hay algo que pueda hacer para aumentar el rendimiento de la prueba EF?

var queries = 10000; // Stored Proc Test Stopwatch spStopwatch = new Stopwatch(); spStopwatch.Start(); for (int i = 0; i < queries; i++ ) { using (var sqlConn = new SlxDbConnection().Connection) { var cmd = new SqlCommand("uspSearchPerformanceTest", sqlConn) { CommandType = CommandType.StoredProcedure }; cmd.Parameters.AddWithValue("@searchText", "gstrader"); sqlConn.Open(); SqlDataReader dr = cmd.ExecuteReader(); List<User> users = new List<User>(); while (dr.Read()) { users.Add(new User { IsAnonymous = Convert.ToBoolean(dr["IsAnonymous"]), LastActivityDate = Convert.ToDateTime(dr["LastActivityDate"]), LoweredUserName = dr["LoweredUserName"].ToString(), MobileAlias = dr["MobileAlias"].ToString(), UserId = new Guid(dr["UserId"].ToString()), UserName = (dr["UserName"]).ToString() }); } var username = users.First().UserName; sqlConn.Close(); } } spStopwatch.Stop(); Console.WriteLine("SP - {0} Queries took {1}", queries, spStopwatch.ElapsedMilliseconds ); // EF Test Stopwatch entityStopWatch = new Stopwatch(); var context = new SlxDbContext(); var userSet = context.Set<User>(); entityStopWatch.Start(); for (int i = 0; i < queries; i++) { User user = userSet.Where(x => x.UserName == "gstrader").First(); } entityStopWatch.Stop(); Console.WriteLine("Entity - {0} Queries took {1}", queries, entityStopWatch.ElapsedMilliseconds);

Resultado:

SP - 10000 Las consultas tomaron 2278

Entidad - 10000 consultas tomaron 16277


De acuerdo con @Wouter de Kort ... Además, cuando necesite pasar a procedimientos, puede usar EF junto con procedimientos para ayudar a la migración de uno a otro.

Pasar a los procedimientos será más rápido en una aplicación típica si unifica la funcionalidad en procedimientos bien diseñados. es decir, obtener todo el trabajo realizado en una llamada sproc como sea posible. Por ejemplo, en una aplicación MVC de carrito de compras cuando un usuario hace clic en el botón de extracción, puede usar el ORM para hacer algo como:

  1. buscar la autenticación de un usuario (¿sigue siendo válido el inicio de sesión?)
  2. buscar permisos (¿pueden comprar dichos artículos ?, ¿hay requisitos especiales?)
  3. buscar cantidades de stock para asegurarse de que no se agotaron en el proceso
  4. escribir a DB para reservar (eliminar del inventario disponible) los artículos antes del pago
  5. buscar información de pago
  6. registrando ...?

O puede tratarse de pasos completamente diferentes, pero en cualquier caso, el punto es que la aplicación MVC usará un ORM para realizar múltiples llamadas al DB para pasar al siguiente paso.

Si toda esta lógica está encapsulada en un sproc bien escrito, entonces solo hay una llamada al sproc y listo. Con la ruta MVC-ORM, los datos deben copiarse de la base de datos al controlador y enviarse a ORM (generalmente a través de la red a un host diferente) y luego leerlos en la aplicación MVC para tomar una decisión simple y luego repetir hasta completar todos los pasos . En el caso de utilizar un sproc que encapsula ese paso de salida, hay mucho menos copia de datos y movimiento por realizar, menos IO de red, menos cambio de contexto, etc.

Piense en la solución MVC-ORM de esta manera. La persona "A" conoce solo los hechos y la persona "B" tiene la habilidad de tomar decisiones con hechos determinados que no plantea. La persona "B" envía un correo electrónico a "A" para conocer los hechos. Según la respuesta de "A", "B" podría solicitar algunos datos más antes de tomar una decisión. Eso es un montón de mensajes de ida y vuelta.

Si tiene una persona que tiene todos los datos y el conocimiento para tomar decisiones, solo tiene que hacer una pregunta y su cerebro procesará todo internamente para obtener una respuesta. No hay deliberación con otra persona involucrada. Naturalmente, va a ser más rápido.

Eso no quiere decir que sea necesariamente mejor . Separar los hechos de la decisión significa que estos componentes son reemplazables / comprobables por separado; sin embargo, si está casado con su MVC y su base de datos, entonces eso es un "no problema".

Por otro lado, muchos fanáticos de MVC odian escribir SQL, por lo que consideran poner cualquier lógica de decisión en SQL como un desastre natural. Para estas personas es imperativo tener cualquier lógica escrita en el mismo idioma que utiliza el MVC porque acelera el desarrollo para ellos. En algunos casos, esto también es un "no problema", ya que en el caso de algunos RDMBS puede escribir sprocs en el mismo idioma que el MVC (ejemplos: .Net - Los sprocs de SQL Server se pueden escribir en C # y usar .Net; las funciones Postgresql (sin sprocs) se pueden escribir en Perl, Python, PHP et al.) La ventaja en este caso es que puede tener sprocs rápidos que encapsulan varios pasos en una llamada y puede usar un lenguaje de programación que usted ya son rápidos en la codificación en.


Hay algunas cosas que puede hacer para optimizar su consulta. Aquí en MSDN puede encontrar una buena descripción general.

Pero para ser honesto, un procedimiento almacenado con mapeo manual siempre será más rápido en rendimiento. Pero pregúntese, ¿qué tan importante es el rendimiento? En la mayoría de los proyectos, el tiempo de desarrollo es mucho más importante que el rendimiento. ¿Qué fue más difícil de desarrollar? ¿La consulta cruda con el análisis o la consulta de Entity Framework?

Los ORM no están diseñados porque funcionan mucho mejor que un enfoque escrito a mano. ¡Los usamos porque el desarrollo es mucho más fácil!

Si escribe su aplicación con Entity Framework y oculta todas sus consultas detrás de un patrón de repositorio, puede desarrollarla muy rápido y luego, cuando el rendimiento se convierte en un problema, mida su aplicación para detectar el cuello de botella. Entonces quizás algunas de sus consultas necesiten optimización y puedan moverse a procedimientos almacenados y mapeo manual.