¿Cómo reducir el crecimiento del registro de transacciones para nvarchar por lotes actualizaciones (max)

StackOverflow https://stackoverflow.com/questions/2014670

Pregunta

Nuestra aplicación necesita añadir grandes cantidades de texto a la base de datos de SQL Server 2005 (hasta 1 GB para un solo registro). Por motivos de rendimiento, esto se hace en trozos, haciendo una llamada de procedimiento almacenado para cada trozo (por ejemplo, usp_AddChunk). usp_AddChunk no tiene ningún transacciones explícitas.

Lo que estoy viendo es que la reducción del tamaño del fragmento de 100 MB a 10 MB resultados en los registros de transacciones de forma masiva grandes. Me han dicho que esto es debido a que cada vez usp_AddChunk se llama, una transacción "implícita" (mi término) registrará todo el texto existente. Por lo tanto, para un registro de 150 MB:

Tamaño 100MB trozo: 100 (0 bytes registrada) + 50 (100 MB registrada) = 100 MB registrados

será menor que

10 MB tamaño de fragmento: 10 (0 bytes registrada) + 10 (10 MB registrada) + 10 (20 MB registrada) ... + 10 (140 MB registrada) = 1050 MB registran

pensé que con la apertura de una transacción en mi código C # (antes de agregar el primer trozo, y se comprometen después de que el último fragmento), esta transacción "implícita" no ocurriría, y podría evitar los enormes archivos de registro. Pero mis pruebas muestran el registro de transacciones crece 5 veces más grandes mediante la transacción de ADO.NET.

No voy a publicar el código, pero aquí hay algunos detalles:

  1. Me llamo SqlConnection.BeginTransaction ()
  2. utilizo un SqlCommand diferente para cada trozo
  3. I asignar el SqlTransaction a partir de (1) a cada SqlCommand
  4. Por lo general cerrar la conexión después de cada ejecución SqlCommand, pero he tampoco trató de cerrar la conexión con los mismos resultados

¿Cuál es la falla en este esquema? Hágame saber si necesita más información. Gracias!

Nota: el uso de un modelo de recuperación simple o de registro masivo no es una opción

¿Fue útil?

Solución

Si por 'trozos' quiere decir algo como:

UPDATE table
SET blob = blob + @chunk
WHERE key = @key;

A continuación, tienes razón en que la operación se registra por completo. Debe seguir la pautas de uso y el uso BLOB los métodos Escriba los para actualizaciones chuncked:

UPDATE table
SET blob.Write(@chunk, NULL, NULL)
WHERE key = @key;

Esto mínimamente registrar la actualización (si es posible, consulte operaciones que se pueden mínimamente registrada):

  

La instrucción UPDATE se registra por completo;   Sin embargo, las actualizaciones parciales a gran   tipos de datos utilizando el valor .WRITE   cláusula se registra mínimamente.

No sólo que este se registra mínimamente, pero debido a que la actualización es una escritura explícita al final de la burbuja, el motor va a saber que sólo se ha modificado una parte del BLOB y sólo registrará que . Cuando se actualiza con el motor SET blob=blob+@chunk te va a ver que todo el BLOB ha recibido un nuevo valor y no detectará el hecho de que realmente sólo cambió el BLOB añadiendo nuevos datos, por lo que el que va a registrar todo el BLOB (varias veces, como ya descubierto).

Por cierto que debe utilizar trozos de tamaño múltiplo de 8040:

  

Para obtener un mejor rendimiento, se recomienda   insertar o actualizar datos en ese   Los tamaños de porción que son múltiplos de 8040   bytes.

Otros consejos

Lo que puede que tenga que hacer es rodear cada "trozo" o grupo de trozos con su propia transacción y cometen después de cada grupo. Que rodea toda la cosa con su propia transacción de ADO está haciendo esencialmente lo mismo que la transacción implícita hace, por lo que no va a ayudar. Usted tiene que comprometerse en trozos más pequeños para mantener el registro más pequeño.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top