Reclamar espacio en disco después de eliminar el campo de tabla

16

Estoy ejecutando sql 2008 r2 y el db funcionó bien y rápido durante los últimos 3 años hasta hace unos 3 meses, agregamos ntext field en una tabla muy activa y usada. Ahora estamos comenzando a salir del espacio del servidor debido al enorme tamaño de expansión de esta tabla.

Leí que la reducción, no queremos perder la indexación de db porque funcionó rápido durante años y no queremos que se gaste la fragmentación.

Decidimos eliminar ese campo y todos sus valores: ¿Hay alguna forma de eliminar el campo ntext y todos sus valores y liberar espacio sin eliminar la indexación, sin reducir, sin perder el rendimiento de db?

Adjunto la salida de consulta de tamaño de base de datos para mostrarle la expansión de tamaño de los últimos 5 meses.

ingrese la descripción de la imagen aquí

usuario1021182
fuente

Respuestas:

12

Decidimos eliminar ese campo y todos sus valores: ¿Hay alguna forma de eliminar el campo ntext y todos sus valores y liberar espacio sin eliminar la indexación, sin reducir, sin perder el rendimiento de db?

Recomendaría usar (de BOL:)

DBCC CLEANTABLE
(
    { database_name | database_id | 0 }
    , { table_name | table_id | view_name | view_id }
    [ , batch_size ]
)
[ WITH NO_INFOMSGS ]

DBCC CLEANTABLE reclama espacio después de que se descarta una columna de longitud variable. Una columna de longitud variable puede ser uno de los siguientes tipos de datos: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), text, ntext, image, sql_variant y xml. El comando no reclama espacio después de que se descarta una columna de longitud fija.

!! PRECAUCION !! ( use un tamaño de lote cuidadoso ; es recomendable usar este parámetro si su tabla es masiva) :

DBCC CLEANTABLE se ejecuta como una o más transacciones. Si no se especifica un tamaño de lote , el comando procesa toda la tabla en una transacción y la tabla se bloquea exclusivamente durante la operación . Para algunas tablas grandes, la longitud de la transacción individual y el espacio de registro requerido pueden ser demasiado. Si se especifica un tamaño de lote, el comando se ejecuta en una serie de transacciones, cada una de las cuales incluye el número especificado de filas. DBCC CLEANTABLE no se puede ejecutar como una transacción dentro de otra transacción.

Esta operación está completamente registrada.

Una simple reproducción demostrará que DBCC CLEANTABLEes mejor que SHRINKING (y no te preocupes por la fragmentación :-)

-- clean up
drop table dbo.Test

-- create test table with ntext column that we will drop later
create table dbo.Test (
    col1 int
    ,col2 char(25)
    ,col3 ntext
    );

-- insert  1000 rows of test data
declare @cnt int;

set @cnt = 0;

while @cnt < 1000
begin
    select @cnt = @cnt + 1;

    insert dbo.Test (
        col1
        ,col2
        ,col3
        )
    values (
        @cnt
        ,'This is a test row # ' + CAST(@cnt as varchar(10)) + 'A'
        ,REPLICATE('KIN', ROUND(RAND() * @cnt, 0))
        );
end

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

--drop the ntext column
ALTER TABLE dbo.Test DROP COLUMN col3 ;

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

--reclaim the space from the table
-- Note that my table is only having 1000 records, so I have not used a batch size
-- YMMV .. so find a maintenance window and you an appropriate batch size 
-- TEST TEST and TEST before implementing in PROD.. so you know the outcome !!
DBCC CLEANTABLE('tempdb', 'dbo.Test') ;

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Kin Shah
fuente
Después de ejecutar el comando DBCC CLEANTABLE, debe RECONSTRUIR su índice agrupado en caso de que la tabla tenga uno, para recuperar el espacio. ALTERAR ÍNDICE IndexName EN YourTable REBUILD;
Sr. TA
6

Para la mayoría de las partes, me refiero a la serie de blogs Inside the storage engine de Paul Randall .

La única forma de recuperar el espacio no utilizado de los archivos de la base de datos en SQLServer es utilizando el comando DBCC SHRINK que reasigna los datos dentro de los archivos de la base de datos liberando páginas y después de eliminarlos del mapa de Global Alcation los elimina del archivo de la base de datos. Esta operación es lenta, crea fragmentación dentro de la base de datos y es aún más lenta cuando se trata de páginas LOB, ya que se almacenan como listas vinculadas dentro de los archivos de la base de datos.

Como está soltando la columna NTEXT, tendrá que esperar a que el proceso de limpieza fantasma elimine los datos antes de reducirse.

Ahora que tiene un montón de espacio libre en los archivos de la base en realidad le hará ningún daño, si usted tiene el espacio en disco, la compresión de copia de seguridad se hará cargo del espacio libre dentro de los archivos.

Si a pesar de todo quiere hacer los archivos más pequeños se puede crear un nuevo grupo de archivos con la base de datos y que sea el predeterminado y luego mover las tablas en el nuevo grupo de archivos, pero esto puede tomar tiempo y causa el tiempo de inactividad. He utilizado la técnica explicada aquí por Bob Pusateri con resultados buenos.

Spörri
fuente
será el proceso de limpieza fantasma reducirá el espacio o reducir también se requiere?
user1021182
siempre tendrá que reducir, el proceso de limpieza solo vacía las páginas asignadas pero no las elimina de los archivos de la base de datos
Spörri
1
@ Spörri Since you are dropping the NTEXT column you will have to wait for the ghost cleanup process to drop the data before shrinking.favor ver mi respuesta . Se puede utilizar DBCC CLEANTABLEpara liberar el espacio.
Kin Shah
4

¿Desea reducir los archivos de la base de datos porque necesita ese espacio para otras bases de datos / archivos no DB o porque tiene problemas con esta base de datos que se está quedando sin espacio?

Si es el segundo, entonces es posible que no tenga un problema tan grande como cree. Si estoy en lo cierto, su problema es cuando la base de datos necesita crecer para ganar espacio adicional para nuevos datos. Una vez que elimine la columna, todo el espacio ocupado por esa columna se liberará para que se agreguen nuevas filas a las tablas en la base de datos. Esto significa que pasará más tiempo antes de que su base de datos necesite crecer. Mientras tanto, obtendría espacio adicional para su unidad de datos. La mayoría de las bases de datos crecen con el tiempo y es bueno tener un buen margen de espacio libre en el disco.

Kenneth Fisher
fuente
solo nos quedan 10 gb de espacio en disco y también se agotará en pocos días. hemos eliminado todo lo que pudimos eliminar del servidor y hemos utilizado las limpiezas y las actualizaciones de Windows detenidas y las hemos eliminado todas y limpiado el winsxs, ahora debemos reducir el tamaño del archivo db
user1021182
Nuevamente, recuerde que una vez que haya eliminado la columna adicional, su crecimiento de la base de datos se detendrá por un tiempo mientras llena el nuevo espacio que liberó. Si su base de datos sigue creciendo después de este punto, necesitará espacio en disco adicional para su base de datos. Posiblemente añadir una nueva unidad a su servidor.
Kenneth Fisher
0

Crearía una tabla espejo sin la columna ofensiva, copiaría todos los datos en esta tabla, soltaría el original y luego cambiaría el nombre de la tabla espejo.

ardochhigh
fuente
en ese caso, todos los índices también deberán estar preparados
usuario 1021182
Sí necesitarán los índices alguna que afectan a la mesa para ser descendido y recreado también .... también se aplica a otros objetos que hacen referencia a la tabla por ejemplo: disparadores
ardochhigh