Transferencia de gran cantidad (84 millones de filas) de datos de manera eficiente

11

Tengo alrededor de 84 millones de filas. De ellos, todos deben transferirse a una base de datos separada en el mismo servidor, luego elimino para eliminar aproximadamente 60 millones de filas de la base de datos de origen.

Los 84 millones de filas están todos en la misma tabla. Esa tabla sola representa el 90% de toda la base de datos.

Entonces ... Fuente: 84 millones de filas -> 24 millones de filas Destino: 0 filas -> 84 millones de filas

La fuente está ejecutando el modo de recuperación completa, el destino se ejecutará de manera simple.

Me pregunto cuál sería la forma más eficiente de hacer esto.

Plan A:

1) INSERTAR EN EL SELECCIÓN DE Destino * DESDE la fuente

2) fuente TRUNCATE

3) INSERTE EN la fuente SELECCIONE * DESDE el destino DONDE keep_condition = 1

Plan B:

1) Restaurar una copia de seguridad de la base de datos de origen como la base de datos de destino

2) Descarte todas las tablas excepto la necesaria en la base de datos de destino

3) fuente TRUNCATE

4) INSERTE EN la fuente SELECCIONE * DESDE el destino DONDE keep_condition = 1

Plan C:

1) INSERTAR EN EL SELECCIÓN DE Destino * DESDE la fuente

2) BORRAR fuente DONDE keep_condition = 0

¿o algo mas?

Gracias

elty123
fuente
¿Por qué no utiliza el asistente de Importar y Exportar datos? Es una herramienta provista con la instalación de SQL Server.
Hani El Mouallem
¿Es posible copiar las filas de 24 mil a una nueva tabla, luego simplemente cambiar el nombre de las dos según sea necesario para que nunca mueva 84 millones de filas innecesariamente?
LowlyDBA
¿Es este un proceso único o continuo? Pregunto porque, dado el tiempo que llevará procesar 80 millones de filas, es probable que haya cambios de datos en las filas productoras de FUENTE que ahora deberían vivir en DESTINO.
Michael Green
Esto parece un problema XY: debe terminar con todas las filas de 84MM en una base de datos, y 24MM de esas en una segunda base de datos. ¿Qué requisito comercial requiere que se muevan 84MM y se eliminen 60M, en lugar de solo mover 24MM? enlace: meta.stackexchange.com/questions/66377/what-is-the-xy-problem )
Pieter Geerkens
Tengo un problema muy similar y claramente no es XY. Antes de la proliferación de leyes relativas a la retención de registros, guardamos todos los datos. Ahora debemos eliminar las filas anteriores a la fecha legalmente requerida para mantenerlas. Esto significa archivar y eliminar más de 20 años de datos porque la retención legal en la mayoría de los casos es de 7 años. No creo que esté solo al creer que Microsoft es negligente al no proporcionar la funcionalidad de 'copia masiva' a los procedimientos almacenados. Una aplicación no debería ser más rápida en el movimiento de datos 'dentro' de una base de datos que la propia base de datos. El próximo año se debe archivar otro año.
bielawski

Respuestas:

11

Agregaría que, sin embargo, si decide abordar esto, deberá agrupar estas transacciones . Últimamente he tenido muy buena suerte con el artículo vinculado, y aprecio la forma en que aprovecha los índices en lugar de la mayoría de las soluciones por lotes que veo.

Incluso mínimamente registrado, esas son grandes transacciones , y podría pasar mucho tiempo lidiando con las ramificaciones del crecimiento anormal de registros (VLF, truncamiento, tamaño correcto, etc.).

Gracias

Erik Darling
fuente
3

"Eficiente" podría aplicarse al uso del archivo de registro, el rendimiento de E / S, el tiempo de CPU o el tiempo de ejecución.

Intentaría lograr una operación mínimamente registrada, que sería bastante eficiente desde una perspectiva de registro. Esto debería ahorrarle tiempo de ejecución como un bono. Si tiene el espacio tempdb, lo siguiente podría funcionar para usted.

CREATE TABLE #temp;
ALTER source -> BULK_LOGGED recovery model

BEGIN TRANSACTION;

    INSERT INTO dest SELECT FROM source;
    INSERT INTO #temp SELECT FROM source WHERE keep_condition=1;
    TRUNCATE TABLE source;
    INSERT INTO source SELECT FROM #temp;

COMMIT TRANSACTION;

ALTER source -> FULL recovery model
DROP TABLE #temp;

Para que se produzca una operación mínimamente registrada, deben cumplirse una serie de condiciones, incluidas las copias de seguridad actualmente en ejecución, la base de datos configurada en BULK_LOGGEDmodo de recuperación y, según sus índices, la tabla de destino puede estar vacía. Parte de este comportamiento también cambió (mejoró) de SQL Server 2005 a 2008.

Por otra parte, sin conocer los detalles de su tabla y datos, cualquiera de sus otras opciones puede funcionar mejor. Intenta usar

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

.. y ver cuál funciona mejor.

EDITAR : al realizar operaciones de registro masivo, asegúrese de realizar una copia de seguridad (registro completo o de transacciones) antes y después de la operación si necesita la capacidad de restauración en un momento dado y sospecha que puede estar ocurriendo otra actividad en la base de datos en Al mismo tiempo que su trabajo ETL se está ejecutando.

Escribí una publicación de blog sobre operaciones mínimamente registradas hace un tiempo, hay enlaces allí a otras publicaciones y documentación.

Daniel Hutmacher
fuente
+1 por aconsejar a OP que pruebe para ver cuál funciona mejor. Por supuesto, eso puede ser un poco difícil obtener números reales a menos que (s) que tiene un sistema duplicado en dev, etc
Max Vernon
Solo una pregunta, ¿qué sucedería si intenta hacer una restauración en un momento dado cuando la base de datos estaba en modo de registro masivo? Supuse que cualquier transacción que no esté calificada como "masiva" sería recuperable.
elty123
1
@ elty123 En la recuperación masiva registrada solo puede restaurar al final de su última copia de seguridad de registro. No hay ningún punto en el tiempo de recuperación como lo habría con una recuperación completa. Normalmente, cambia a la recuperación registrada en masa, ejecuta un proceso ETL, vuelve a la completa y luego realiza una copia de seguridad del registro.
RubberChickenLeader
@WindRaven Esto no es correcto; vea mi respuesta a continuación.
wBob
1
@wBob y @WindRaven, he actualizado mi respuesta para reflejar la necesidad de realizar copias de seguridad antes y después de usar el BULK_LOGGEDmodo. ¡Gracias!
Daniel Hutmacher
1

¿Por qué no BCP?

  1. Copia de seguridad de la fuenteb
  2. Cambiar de fuenteb a registro masivo
  3. Abrir símbolo del sistema

  4. bcp server.sourcedb.table out Filename.flt -T -c

  5. bcp "SELECT * FROM sourcedb.table WHERE keep_condition = 1" queryout Filename2.flt -T -c

  6. bcp Server.destinationdb.table in Filename.flt -T -c -b1000

  7. verificar los datos

  8. Desde SSMS Truncar la tabla sourcedb
  9. bcp server.sourcedb.table in Filename2.flt -T -c -b1000
  10. Cambiar fuenteb de nuevo a completo
Stacylaray
fuente
2
Porque están en el mismo servidor. Escribir en el sistema de archivos sería costoso. Es mejor crear una base de datos y ajustarla, con suerte aprovechando la inicialización instantánea de archivos. Esta sería una opción razonable para dbs en diferentes servidores, aunque SSIS sería mi primera opción si estuviera disponible. NB: la opción -n (nativa) es más compacta y segura para mover datos de SQL Server a SQL Server. La opción -b no tiene efecto para bcp out.
wBob
0

No piense que debería recomendar cambiar el modelo de recuperación sin una copia de seguridad completa de la base de datos o una copia de seguridad de t-log antes y después . Una de las características del modelo de recuperación BULK_LOGGED es que perderá la capacidad de realizar una recuperación en un punto en el tiempo para los registros t que contienen operaciones de registro masivo. Escenario clásico: copia de seguridad completa nocturna, copias de seguridad t-log por hora. Cambia el modelo de recuperación a registro masivo e inicia su operación. Algo sale mal y la transacción se revierte (o no ha usado uno). Sin embargo, no está seguro de qué más estaba sucediendo en la base de datos, por lo que desea restaurar a un buen punto conocido.

¿Cuándo puedes volver a restaurar? La última copia de seguridad de t-log por hora que no contiene operaciones de registro masivo, lo que podría perder n minutos de transacciones. Una copia de seguridad completa o una copia de seguridad de t-log antes de cambiar el modelo de recuperación creará un punto de reserva. El que elija depende de su RTO.

wBob
fuente
0

Eliminar particiones de una tabla es una forma realmente rápida y eficiente en cuanto a recursos para eliminar grandes cantidades de datos de una tabla. Si esta tabla se particionara de manera que sea compatible con su origen / destino, la respuesta sería restaurar una copia, eliminar las tablas redundantes y las particiones redundantes del destino y eliminar las particiones complementarias del origen.

Sin embargo, el costo de habilitar la partición puede hacer que esta sea una operación más costosa en general.

Michael Green
fuente