Cómo reducir el tamaño de la tabla de SQL Server que creció a partir de un cambio de tipo de datos

StackOverflow https://stackoverflow.com/questions/807579

Pregunta

Tengo una tabla en SQL Server 2005 que tenía un tamaño de aproximadamente 4 gb.

(alrededor de 17 millones de registros)

Cambié uno de los campos del tipo de datos char (30) a char (60) (hay un total de 25 campos, la mayoría de los cuales son char ( 10) por lo que la cantidad de espacio de charla se suma a aproximadamente 300)

Esto hizo que la tabla duplicara su tamaño (más de 9 gb)

Luego cambié char (60) a varchar (60) y luego ejecuté una función para eliminar los espacios en blanco de los datos (para reducir el promedio). longitud de los datos en el campo a aproximadamente 15)

Esto no redujo el tamaño de la tabla. Reducir la base de datos tampoco ayudó.

Además de recrear realmente la estructura de la tabla y copiar los datos (¡eso es 17 millones de registros!) ¿hay una forma menos drástica de volver a bajar el tamaño?

¿Fue útil?

Solución

¡Está claro que no estás recuperando espacio! :-)

Cuando cambiaste los campos de texto a CHAR (60), todos se llenan a capacidad con espacios. Entonces, TODOS los campos tienen realmente 60 caracteres de longitud.

Cambiar eso de nuevo a VARCHAR (60) no servirá de nada, los campos siguen teniendo 60 caracteres de longitud ...

Lo que realmente necesitas hacer es ejecutar una función TRIM en todos tus campos para reducirlos a su longitud recortada, y luego reducir la base de datos.

Después de que hayas hecho eso, necesitas RECONSTRUIR tu índice agrupado para recuperar algo de ese espacio desperdiciado. El índice agrupado es realmente donde viven sus datos, puede reconstruirlos de esta manera:

ALTER INDEX IndexName ON YourTable REBUILD 

De forma predeterminada, su clave principal es su índice agrupado (a menos que haya especificado lo contrario).

Marc

Otros consejos

No ha limpiado ni compactado ningún dato, ni siquiera con una " base de datos reducida " ;.

DBCC CLEANTABLE

  

Recupera el espacio de las columnas de longitud variable eliminadas en tablas o vistas indizadas.

Sin embargo, un reconstrucción de índice simple < em> si hay un índice agrupado también debería hacerlo

ALTER INDEX ALL ON dbo.Mytable REBUILD

Un ejemplo trabajado de Tony Rogerson

Sé que no estoy respondiendo a su pregunta como lo está haciendo, pero ¿ha considerado archivar algunos de los datos en una tabla de historial y trabaja con menos filas?

La mayoría de las veces, a primera vista, puede pensar que necesita toda esa información todo el tiempo, pero cuando realmente se sienta y lo examina, hay casos en que eso no es cierto. O al menos he experimentado esa situación antes.

Tuve un problema similar aquí SQL Server, que convierte NTEXT a NVARCHAR (MAX) que estaba relacionado con el cambio de ntext a nvarchar (max).

Tuve que hacer un UPDATE MyTable SET MyValue = MyValue para que cambie el tamaño de todo muy bien.

Esto obviamente lleva bastante tiempo con muchos registros. Hubo una serie de sugerencias sobre cómo hacerlo mejor. La clave uno era una marca temporal que se indicaba si se había hecho o no, y luego se actualizaba unos pocos miles a la vez hasta que todo estuviera terminado. Esto significaba que tenía " algo " control sobre cuánto estaba haciendo.

Sin embargo, en otra nota, si realmente desea reducir la base de datos tanto como sea posible, puede ser útil si reduce el modelo de recuperación a lo simple, reduce los registros de transacciones, reorganiza todos los datos en las páginas y luego configúrelos. Volver al modelo de recuperación completa. Sin embargo, tenga cuidado, la reducción de las bases de datos generalmente no es recomendable, y si reduce el modelo de recuperación de una base de datos activa, está pidiendo que algo salga mal.

Alternativamente, puedes hacer una reconstrucción completa de la tabla para asegurarte de que no haya datos adicionales en cualquier lugar:

CREATE TABLE tmp_table(<column definitions>);
GO
INSERT INTO tmp_table(<columns>) SELECT <columns> FROM <table>;
GO
DROP TABLE <table>;
GO
EXEC sp_rename N'tmp_table', N'<table>';
GO

Por supuesto, las cosas se complican más con la identidad, los índices, etc. etc ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top