6

Estoy trabajando en un proceso por lotes que vuelca ~ 800,000 registros de una base de datos lenta legada (1.4-2ms por registro de tiempo de recuperación ... se suma) en MySQL que puede realizar un poco más rápido. Para optimizar esto, he estado cargando todos los registros de MySQL en la memoria, lo que hace que el uso sea de unos 200 MB. Luego, comienzo a descargar de la base de datos heredada y actualizo los registros.Marco de entidad eliminar objeto del contexto, pero no de la base de datos

Originalmente, cuando esto completaba la actualización de los registros, llamaba a SaveContext para que mi memoria saltara de ~ 500MB-800MB a 1.5GB. Muy pronto, me saldrían las excepciones de memoria (la máquina virtual en la que se ejecuta tiene 2GB de RAM) e incluso si tuviera que darle más RAM, 1.5-2GB es un poco excesivo y eso sería solo poner una banda ayuda sobre el problema Para remediar esto, comencé a llamar a SaveContext cada 10.000 registros que ayudaron a las cosas un poco y como estaba usando delegados para buscar los datos de la base de datos heredada y actualizarlos en MySQL, no recibí un rendimiento demasiado horrible ya que después de la Espere unos 5 segundos mientras se estaba guardando y luego se ejecutará a través de la actualización en la memoria para los aproximadamente 3000 registros que se han copiado. Sin embargo, el uso de memoria sigue aumentando.

Aquí están mis posibles problemas:

  • Los datos provienen de la base de datos existente en cualquier orden, así que no puedo trozo las actualizaciones y la liberación periódicamente ObjectContext.
  • Si no recojo todos los datos de MySQL de antemano y en su lugar lo busco durante el proceso de actualización por registro, es increíblemente lento. En cambio, tomo todo de antemano, lo echo a un diccionario indexado por la clave primaria, y cuando actualizo los datos elimino los registros del diccionario.

Una posible solución pensé es que de alguna manera liberar la memoria utilizada por las entidades que sé que nunca voy a tocar de nuevo, puesto que ya se han actualizado (como borrar la memoria caché, pero sólo por un artículo específico), pero no sé si eso es posible con Entity Framework.

¿Alguien tiene alguna idea?

+1

EF no parece ser la herramienta adecuada para el trabajo. ¿Por qué no migras los datos directamente? – Pawel

+0

Migrar datos utilizando SSIS – fenix2222

Respuesta

6

Usted puede llamar al método Separar en el contexto pasándole el objeto que ya no necesite: http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.detach%28v=vs.90%29.aspx

+0

Aunque puedo terminar alejándome de la infraestructura de la entidad por la velocidad, esto solucionó el problema de memoria. Comencé a guardar el contexto cada 30,000 registros y luego separó los objetos que había actualizado del contexto y dejó de usar tanta memoria. –

2

Me pregunto si la mejor opción no es otra herramienta como se sugirió anteriormente o simplemente renunciar a la utilización de Marco de la entidad. Si en lugar de hacer el código sin un ORM, puede:

  1. Tune declaraciones del SQL para mejorar el rendimiento
  2. Controle fácilmente, y el cambio, el alcance de las transacciones para obtener el mejor rendimiento.
  3. Puede agrupar las actualizaciones para que no llame al servidor para realizar varias actualizaciones en lugar de realizarlas de una en una.
Cuestiones relacionadas