EF 4.0 Performance Tips #1

Ya desde hace algún tiempo me rondaba por la cabeza la idea de poner post con tips de rendimiento a tener en cuenta dentro de Entity Framework 4.0, algunos de ellos serán más habituales y sencillos de resolver, otros por contra puede que sean más complicados de encontrar. Espero que la carga de trabajo me ayude a que los siguientes números no se dilaten demasiado 🙂

 

Empezamos por una sencillita, ¿cual es la diferencia entre las siguientes consultas en Linq2Entities y que impacto podría tener en el rendimiento de las mismas?

A)

La respuesta a esta pregunta es sencilla, para la primera consulta, sin parametrizar, Entity Framework dispara una consulta AdHoc, ni siquiera DSE, con lo cual el plan de ejecución no se reaprovechará si esa misma consulta se realiza con valores de, en este caso, FirstName distintos al actual, forzando por lo tanto un movimiento muy grande de elementos en la cache de planes de ejecución y por lo tanto disminuyendo el rendimiento.

Para el caso de la consulta B, EF ejecuta esta consulta mediante sp_executesql ( Force Statment Caching ), gracias a lo cual esta consulta paremetrizada puede reutilizar el mismo plan de ejecución aun variando los valores de los parámetros.

 

Puede observar las diferencias de estos comportamientos ejecutando la siguiente consulta:

 

SELECT *  from sys.dm_exec_cached_plans cp cross apply sys.dm_exec_sql_text(plan_handle)

 

Untitled

 

 

Saludos

Unai

13 comentarios sobre “EF 4.0 Performance Tips #1”

  1. Al final resulta que tenemos los mismos problemas en EF que en ADO.Net ¡No nos podemos olvidar de la importancia de la paremetrización!.

    Menos más que si el problema es grave y ya le hemos liado parda SQL Server nos puede ayudar:
    http://geeks.ms/blogs/rcorral/archive/2009/12/28/como-detectar-cuando-las-consultas-no-parametrizadas-da-241-an-el-rendimiento-de-sql-server-y-que-hacer.aspx

    Supongo que da igual usar LinqToSQL que LinqToEntities ¿no?.

    !Me encanta la idea de esta serie!

  2. Muy buen post Unai.

    Rodrigo el tuyo también muy bueno.

    Aunque no nos libremos del uso de parametros, me gusta esto de trabajar con EF o con LINQTOSQL!!

  3. Gracias a todos, responde algunos comentarios

    Rodrigo: Con Linq2SQL todas las consultas son parametrizadas :-), cosas de la vidad.

    Dominik, si efectivamente el uso de especificaicones te ayuda a no meter queries adhoc pero tampoco te lo libra si lo haces mal:-)

    Saludos
    Unai

  4. Hola de nuevo,

    Nosotros estamos siguiendo la “Guia de Arquitectura N-Capas orientada al Dominio” en nuestra nueva aplicación.

    Hace unos dias realizamos unas primeras pruebas de rendimiento y a raiz de este post me dedique a revisar las querys SQL generadas.

    Mi sorpresa fue que las querys SQL eran dinamicas, por lo que no se genera plan de ejecucion alguno…

    Como es posible esto? Usando el patron Specification no deberian generarse querys parametrizadas? Estamos haciendo algo mal?

    Saludos.

  5. Buenas Dominik,

    Yo te recomendaría el USO de LINQPad para ver el SQL que se genera y así hacerte una idea del plan de ejecución que tendrá la consulta. Aplica TDD con varios escenarios sobre Especificaciones (Specifications) de consulta y ajusta dicho rendimiento. De todas formas hay que tener en cuenta que el purismo al límite tampoco es bueno, si estás tratando con SQL Server y con consultas muy complejas, podrías implementar una Specification que lanze un Stored Procedure, afectando solamente a esa specification y, en caso de querer cambiarlo que solamente afecte a la specification.

    NOTA: Rodrigo tiene razón. Que bien funciona LINQ2SQL por dios! Y ahora más que en la versión de .net 4.0 ya han arreglado el tema del tamaño de varchars(x) al lanzar Stored Procedures y se reaprovecha la caché del plan de ejecución…

  6. Seguramente este preguntando una tonteria pero… ¿Es recomendable parametrizar cuando se usa Linq to Object o aqui no es necesario porque no trabajamos con ninguna base de datos?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *