sql >> Base de Datos >  >> RDS >> Sqlserver

La forma más rápida de actualizar 120 millones de registros

La única forma sensata de actualizar una tabla de 120 millones de registros es con SELECT declaración que completa un segundo mesa. Hay que tener cuidado al hacer esto. Instrucciones a continuación.

Caso sencillo

Para una tabla sin un índice agrupado, durante un tiempo sin DML concurrente:

  • SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
  • recrear índices, restricciones, etc. en una nueva tabla
  • cambie viejo y nuevo con ALTER SCHEMA... TRANSFER.
  • soltar mesa vieja

Si no puede crear un esquema de clonación, un nombre de tabla diferente en el mismo esquema servirá. Recuerde cambiar el nombre de todas sus restricciones y activadores (si corresponde) después del cambio.

Caso no simple

Primero, vuelve a crear tu BaseTable con el mismo nombre bajo un esquema diferente, por ejemplo, clone.BaseTable . El uso de un esquema separado simplificará el proceso de cambio de nombre más adelante.

  • Incluir el índice agrupado , si es aplicable. Recuerde que las claves primarias y las restricciones únicas pueden agruparse, pero no necesariamente.
  • Incluir columnas de identidad y columnas calculadas , si corresponde.
  • Incluye tu nueva columna INT , donde sea que pertenezca.
  • No incluir cualquiera de los siguientes:
    • desencadenantes
    • restricciones de clave externa
    • índices no agrupados/claves primarias/restricciones únicas
    • verificar restricciones o restricciones predeterminadas. Los valores predeterminados no hacen mucha diferencia, pero estamos tratando de mantener las cosas al mínimo.

Luego, pruebe su inserción con 1000 filas:

-- assuming an IDENTITY column in BaseTable
SET IDENTITY_INSERT clone.BaseTable ON
GO
INSERT clone.BaseTable WITH (TABLOCK) (Col1, Col2, Col3)
SELECT TOP 1000 Col1, Col2, Col3 = -1
FROM dbo.BaseTable
GO
SET IDENTITY_INSERT clone.BaseTable OFF

Examine los resultados. Si todo aparece en orden:

  • truncar la tabla de clones
  • asegúrese de que la base de datos esté en un modelo de recuperación simple o de registro masivo
  • realice la inserción completa.

Esto llevará un tiempo, pero no tanto como una actualización. Una vez que se complete, verifique los datos en la tabla de clones para asegurarse de que todo sea correcto.

Luego, vuelva a crear todas las claves primarias no agrupadas/restricciones únicas/índices y restricciones de clave externa (en ese orden). Vuelva a crear las restricciones predeterminadas y de verificación, si corresponde. Vuelva a crear todos los disparadores. Vuelva a crear cada restricción, índice o disparador en un lote separado. por ejemplo:

ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
GO
-- next constraint/index/trigger definition here

Finalmente, mueva dbo.BaseTable a un esquema de respaldo y clone.BaseTable al esquema dbo (o donde se supone que vive su tabla).

-- -- perform first true-up operation here, if necessary
-- EXEC clone.BaseTable_TrueUp
-- GO
-- -- create a backup schema, if necessary
-- CREATE SCHEMA backup_20100914
-- GO
BEGIN TRY
  BEGIN TRANSACTION
  ALTER SCHEMA backup_20100914 TRANSFER dbo.BaseTable
  -- -- perform second true-up operation here, if necessary
  -- EXEC clone.BaseTable_TrueUp
  ALTER SCHEMA dbo TRANSFER clone.BaseTable
  COMMIT TRANSACTION
END TRY
BEGIN CATCH
  SELECT ERROR_MESSAGE() -- add more info here if necessary
  ROLLBACK TRANSACTION
END CATCH
GO

Si necesita liberar espacio en el disco, puede eliminar su tabla original en este momento, aunque puede ser prudente mantenerla durante un tiempo más.

No hace falta decir que este es idealmente un fuera de línea operación. Si tiene personas modificando datos mientras realiza esta operación, deberá realizar una operación de ajuste con el cambio de esquema. Recomiendo crear un disparador en dbo.BaseTable para registrar todo el DML en una tabla separada. Habilite este activador antes de iniciar la inserción. Luego, en la misma transacción en la que realiza la transferencia del esquema, utilice la tabla de registro para realizar una corrección. ¡Pruebe esto primero en un subconjunto de los datos! Los deltas son fáciles de estropear.