2009-09-22 18 views
21

Tengo una tabla de depósito con 16 toneladas de datos. Tengo algunas columnas enteras en él. Tenemos que convertirlos en BIGINT para cada consulta que escribimos, porque la suma es demasiado grande para caber en una INT.Cambio de INT a BigInt

Ahora tenemos una nueva datamart en desarrollo. Así que pensamos, ¿por qué no cambiar todas estas columnas en BIGINT y tenemos menos de qué preocuparse por el nuevo conjunto de consultas?

Dado que los datos ya están cargados, calculé que usaría Management Studio y cambiaría el tipo de datos. Pero por primera vez aparece una advertencia:

Saving Definition Changes to tables with large amounts of data could take a considerable amount of time. While changes are being saved, table data will not be accessible.

Entonces me da un error:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

¿Cómo consigo alrededor de esto?

+45

16 toneladas de datos - eso es mucho! – RedFilter

+0

¿Ha considerado una tabla temporal, una nueva estructura, insertar y reemplazar? –

+2

@astander - eso es esencialmente lo que el esquema de cambio en SSMS está haciendo bajo el capó. – tvanfosson

Respuesta

43

Si una o más de esas columnas no tienen restricciones en contra de ellos (como una clave externa, índice, por defecto, el Estado, etc.), debe ser capaz de cambiar cada uno de forma rápida haciendo

ALTER TABLE monster ALTER COLUMN MyIntCol1 bigint

El cambio SQL de Management Studio rara vez es el más eficiente y tiende a favorecer las tablas temporales para cualquier cosa que modifique una columna existente.

+1

Interesante, no sabía que Management Studio era ineficiente en ese sentido. – RedFilter

24

No estoy seguro si esto ayudará, pero intente esto:

1 - create a new bigint column in the table 
2 - update that new column with the values from the int column 
3 - delete the int column 
4 - rename the bigint column 
+3

+1, ¡lo mismo que intentaba tipear! –

+0

Lo mismo que estaba escribiendo lo mismo. (+1) Iba a agregar que esto también funciona en la replicación. –

+1

Una cosa a tener en cuenta con esta técnica es que cambiará el orden de las columnas. Si bien esto * debería * estar bien, es posible que en algún lugar, alguien confíe en que este orden sea estable, por ejemplo, cuando seleccionan * e insertan en una tabla temporal. –

2

de ampliar OrbMan's respuesta:

  • añadir las nuevas columnas en la parte inferior de la lista de columnas (esto acelerarlo mucho más)
  • puede hacer sus actualizaciones en lotes de 10.000 filas o más si es necesario
  • asegúrese de que está en modo de usuario único, o la aplicación si está "DESACTIVADA" para que nadie más cambia los datos de esa tabla

También, para ver todo el trabajo que estudio gestora y que cuando se cambia una tabla, haga clic en el icono de la barra de desplazamiento que se parece a uno de arranque en él. Esto mostrará los comandos SQL reales utilizados para modificar su tabla.

7

Creo que el error principal que quizás encuentre es que la GUI es lo que está agotando el tiempo. Cuando aplique un gran cambio utilizando la opción Modificar de SSMS, se agotó el tiempo de espera. Si toma el mismo comando generando el script de cambio en SSMS y luego se ejecuta como una consulta SQL directa, se ejecutará hasta que se complete.

2

Si la fuente de datos nunca supera el límite INT, simplemente haga una VISTA que reubique esa columna en BIGINT y consulte en contra de eso.

7

Esta técnica funcionó muy bien para mí.

ejecuté:

use [Mytable] 
ALTER TABLE [dbo].[USER] ALTER COLUMN USER_ID bigint NOT NULL 

Esto dio lugar a este error porque no había una limitación en la tecla:

Msg 5074, Level 16, State 1, Line 2 
The object 'PK_USER_USER_ID' is dependent on column 'USER_ID'. 
Msg 4922, Level 16, State 9, Line 2 
ALTER TABLE ALTER COLUMN USER_ID failed because one or more objects access this column. 

Sin desanimarse, en SQL Server Management Studio me hace clic derecho en la restricción PK_USER_USER_ID, luego se seleccionó "Script key as >> Drop and Create To >> Nueva ventana del editor de consultas":

enter image description here

Esto generó este script:

USE [Database] 
GO 
/****** Object: Index [PK_USER_USER_ID] Script Date: 18/03/2014 13:05:38 ******/ 
ALTER TABLE [dbo].[USER] DROP CONSTRAINT [PK_USER_USER_ID] 
GO 

/****** Object: Index [PK_USER_USER_ID] Script Date: 18/03/2014 13:05:38 ******/ 
ALTER TABLE [dbo].[USER] ADD CONSTRAINT [PK_USER_USER_ID] PRIMARY KEY CLUSTERED 
(
[USER_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,  ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

entonces ejecuta el primera mitad de este guión, a quitar la restricción:

ALTER TABLE [dbo].[USER] DROP CONSTRAINT [PK_USER_USER_ID] 
GO 

Ahora que la restricción se había ido , el cambio original funcionó muy bien:

use [Mytable] 
ALTER TABLE [dbo].[USER] ALTER COLUMN USER_ID bigint NOT NULL 

entonces ejecuta la segunda mitad del guión, a añadir la restricción de vuelta en:

ALTER TABLE [dbo].[USER] ADD CONSTRAINT [PK_USER_USER_ID] PRIMARY KEY CLUSTERED 
(
[USER_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,  ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 
Cuestiones relacionadas