2012-02-13 9 views
30

Tengo un comportamiento extraño al tratar de ejecutar una consulta que declara ObjectQuery MergeOption como "NoTracking", en este caso entidad framework no debe asociar ninguna entidad y no crear ObjectStateEntry relativa para rastrear estado de entidad.Entity Framework mergeoption notracking bad performance

El problema es que en lugar de aumentar el rendimiento Empeora, la misma consulta tarda como 10 segundos con MergeOption por defecto (es decir AppendingOnly) y más los minutos 1 si intento para especificar notracking

¿Alguien tiene una explicación para esto?

+0

¿Cómo se midieron las ejecuciones de consultas? –

+0

básicamente tomando una marca de tiempo antes y después de la consulta ejecutada con un ToList() – MaRuf

+0

Pero, ¿cuántas veces ejecutas la consulta y qué orden de ejecuciones estás usando? –

Respuesta

100

Si deshabilita el seguimiento de cambios estableciendo la opción de combinación NoTracking, ahorrará los costos de rendimiento de adjuntar objetos a los contextos, pero, por otro lado, también perderá la administración de identidades.

Esto significa que potencialmente se materializarán muchos más objetos, muchos con la misma llave.

Ejemplo: Suponga que tiene una entidad User con una colección Roles como propiedad de navegación. Supongamos también que tiene 1 millón de usuarios en la base de datos y todos los usuarios tienen los mismos 10 roles, es decir, cada usuario tiene una colección de roles con 10 elementos. Si ejecuta la siguiente consulta ...

var users = context.Users.Include("Roles").ToList(); 

... el número de objetos instanciados materializadas y depende de la opción de fusión:

  • Si no se utiliza NoTracking que tendrá 1.000 .010 objetos en la memoria, es decir, 1 millón de usuarios, pero solo 10 roles porque el mapeo de identidades garantizará que solo se haya materializado 1 papel por clave y esté unido al contexto. Las mismas 10 instancias de rol se usan para la colección Roles de todos los usuarios.

  • Sin embargo, EF no asociará objetos al contexto, por lo tanto la gestión de identidades está deshabilitada y tendrá 11.000.000 de objetos en memoria: 1 millón de usuarios y 10 instancias de función por usuario, es decir, 10 millones objetos de rol. Por lo tanto, tiene más de 10 veces más objetos materializados que cuando los objetos están unidos al contexto.

materialización de objetos se clasifica con "moderate" performace costs:

Operación: Materializar los objetos
Costo relativa: Moderado
Frecuencia: Una vez para cada objeto que devuelve una consulta .

Comentarios: El proceso de leer el objeto DbDataReader vuelto y la creación de objetos y el establecimiento de los valores de propiedad que se basan en los valores de cada instancia de la clase DBDataRecord.Si el objeto ya existe en el ObjectContext y la consulta utiliza el appendOnly o PreserveChanges opciones de combinación, esta etapa no afecta al rendimiento.

En otras palabras: si la consulta utiliza la opción NoTracking fusión, esta etapa Cómo afecta el rendimiento y podría ser posible que los beneficios de rendimiento de seguimiento de cambios con discapacidad son destruidos por los inconvenientes de la gestión de identidad con discapacidad y materialización de objetos multiplicada

+1

¡El ejemplo es muy claro! ¡Estupendo! – kingkong0924

+3

(aplauso lento) Aaaa y es por eso que tiene 70k puntos. bien hecho. – SteveCav