2012-05-25 20 views
14

Tengo una tabla en SQL Server 2008 R2 con cerca de mil millones de filas. Quiero cambiar el tipo de datos de dos columnas de int a bigint. Dos veces ALTER TABLE zzz ALTER COLUMN yyy funciona, pero es muy lento. ¿Cómo puedo acelerar el proceso? Estaba pensando en copiar los datos en otra tabla, soltar, crear, copiar de nuevo y cambiar al modo de recuperación simple o de alguna manera hacerlo con un cursor de 1000 filas por vez, pero no estoy seguro de si realmente se logrará alguna mejora.Cambiar los tipos de columna en una tabla enorme

+1

¿Puede explicar de qué está cambiando el tipo de datos desde y hacia? –

+1

No veo cómo podría usar un cursor para cambiar el tipo de columna? Un tipo de columna es un cambio a _todos_ valores en una tabla. – Oded

+0

ints to bigints – user1417408

Respuesta

26

Según el cambio que realice, a veces puede ser más fácil tomar una ventana de mantenimiento. Durante esa ventana (en la que nadie debería ser capaz de cambiar los datos en la tabla) se puede:

  1. caída de los índices/restricciones que apuntan a la columna de edad, y los disparadores desactivar
  2. añadir un nuevo columna anulable con el nuevo tipo de datos (incluso si debe ser NOT NULL)
  3. actualice la nueva columna configurándola igual al valor de la columna anterior (y puede hacerlo en fragmentos de transacciones individuales (por ejemplo, afectando a 10000 filas en una tiempo usando UPDATE TOP (10000) ... SET newcol = oldcol WHERE newcol IS NULL) y con CHECKPOINT para evitar sobrepasar su registro)
  4. Una vez que las actualizaciones se puede hacer todo, la caída de la antigua columna
  5. cambiar el nombre de la nueva columna (y añadir una restricción NOT NULL en su caso)
  6. reconstruir los índices y las estadísticas de actualización

La clave aquí es que le permite para realizar la actualización de forma incremental en el paso 3, lo cual no se puede hacer en un solo comando ALTER TABLE.

Esto supone que la columna no juega un papel importante en la integridad de los datos: si está involucrado en un conjunto de relaciones de claves externas, hay más pasos.

EDITAR

también, y sólo me preguntaba en voz alta, no he hecho ninguna prueba para esto (pero añadiendo a la lista). Me pregunto si la compresión de página + fila ayudaría aquí? Si cambia una INT a una BIGINT, con la compresión en su lugar SQL Server debería tratar todos los valores como si todavía encajaran en una INT. Una vez más, no he probado si esto haría que un cambio sea más rápido o más lento, o cuánto tiempo más tomaría agregar compresión en primer lugar. Solo tirarlo ahí afuera.

+0

La base de datos estará fuera de línea. ¿Establecer el modelo de recuperación a simple ayuda? – user1417408

+0

En SIMPLE o FULL, su gran comando ALTER TABLE no será diferente, ya que todo se registra en ambos casos. Con lo anterior, SIMPLE podría ser un poco mejor, pero el modelo de recuperación no debería importar si elige un tamaño de lote apropiado. Además, si la base de datos está "fuera de línea" (supongo que no quiere decir ALTER DATABASE ... SET OFFLINE), ¿por qué la velocidad es importante? Lo anterior probablemente afeitaría un porcentaje del tiempo, pero no será alucinantemente más rápido. Lo que estás haciendo simplemente lleva tiempo. –

+0

Aaron, gracias por su ayuda. La velocidad es importante porque el sitio que usa este DB solo estará fuera de línea durante unas horas. – user1417408

-2

Si está utilizando algo como SQL Server Management Studio, vaya a la tabla en la base de datos, haga clic con el botón derecho, seleccione 'Diseño' y luego elija la columna que desea editar: establézcalo en bigint y presione guardar. Cambia toda la columna, pero los valores anteriores permanecerán como están. Esto es bueno para permitir que una tabla 'crezca' de int a bigint, pero no cambiará los datos existentes hasta donde yo sé.

Cuestiones relacionadas