Tenemos una serie de bases de datos que almacenan de 10 a 100 gigabytes de datos en una de las tablas. Contiene datos de imagen. El problema es que muchas de estas bases de datos se crearon de forma incorrecta. Básicamente, la clave principal no es en realidad una clave principal. Se crearon con un índice único en una columna que admite nulos. Y algunos de ellos tienen un int como clave principal en lugar de un bigint.Manera eficiente de alterar la tabla de 100 GB
Estamos revisando y arreglando estas bases de datos. Se ejecutan en SQL Server 2000 a través de SQL Server 2008, aunque la mayoría de los que tienen problemas de clave primaria están en SQL Server 2000. El problema es que no queremos bloquear la base de datos durante todo un día mientras se convierte la tabla. Hemos analizado varias estrategias:
Indique a SQL Server que cambie directamente el tipo de columna. Esto bloquea la tabla hasta que esté completa, y después de dejarla durante la noche en muchos casos, aún no se terminó.
Inserte todas las imágenes en una nueva tabla de una vez. Esto se interrumpió más fácilmente, pero la tabla completa básicamente se escribe en el archivo de registro en el proceso.
Insertar 100 filas a la vez, donde no existen las filas de la tabla de destino. Lo bueno es que pueden seguir usando la base de datos mientras esto sucede (con un gran impacto en el rendimiento) y que puede detenerse y reiniciarse arbitrariamente en cualquier punto, y evita los archivos de registro de 100 GB +. Esto es lo que estamos haciendo actualmente, pero encontrar las 100 mejores filas que no existen se vuelve muy lento a medida que la tabla objetivo se hace cada vez más grande. UPDATE STATISTICS y DBCC INDEXDEFRAG ayudan considerablemente, pero en el intento más reciente, llegamos al punto de que incluso 100 imágenes a la vez estaban sentadas allí sin responder.
INSERT INTO %s SELECT TOP 100 Source.* FROM %s AS Source WITH (NOLOCK) LEFT OUTER JOIN %s AS Target WITH (NOLOCK) ON Source.DocumentID = Target.DocumentID WHERE Target.DocumentID IS NULL ORDER BY Source.DocumentID
Así que la pregunta es, ¿hay una opción que puede copiar los datos a granel de una manera eficiente y resumable? No tiene que ser 100% exacto, siempre podemos regresar y corregir cualquier discrepancia al final, siempre que haga el 99% del trabajo.
La clave principal en esta tabla no está agrupada. La conversión a un índice agrupado sería casi tan doloroso como recrear la tabla, porque tiene que reorganizar físicamente todos los datos. –
Hacerlo por rangos es definitivamente más eficiente que el método de unión. Tendré que ver cómo funciona en la práctica, pero lo que esperaba era que hubiera alguna manera de ejecutar las inserciones de una manera no atómica, donde si se detiene a medio camino, dejaría lo que ya está hecho, y evitar la escritura extra en el archivo de registro. –
@Bryce Wagner: si no está agrupado en PK, realice un rango o agrupación equivalente en lo que * esté * en clúster. (Por favor dígame si tiene un clúster, y que no es solo un HEAP) – BradC