La mejor manera de desfragmentar / compactar una base de datos con fines de archivo


9

Tenemos una instancia de SQL Server que se utiliza para el archivo de correo electrónico (cortesía de un paquete de archivo de terceros). De vez en cuando, el software se transfiere a una nueva base de datos vacía. Hemos hecho esto trimestralmente en el pasado, pero estamos buscando hacerlo mensualmente ahora. La cantidad de datos que se archiva es de aproximadamente 15-20 GB por mes, y la mayor parte de los datos reside en solo un puñado de tablas (generalmente de 2 a 4).

Una vez que pasamos a una nueva base de datos, la antigua se usa solo para lectura. Lo que me gustaría hacer es optimizarlo en un archivo de datos agradable y ajustado, con todas las tablas / índices contiguos y con un factor de relleno muy alto, y sin mucho espacio vacío al final del archivo de datos. Además, estamos usando Standard Edition en este servidor, con todas las limitaciones que eso implica (de lo contrario, ya estaría usando la compresión de datos).

Algunas posibilidades que se me ocurren:

  1. RECONSTRUIR / REORGANIZAR índices, DBCC SHRINKFILE (De acuerdo, esta no es una opción sensata, ya que DBCC SHRINKFILE fragmentará la orina de todo lo que toque, pero lo estoy incluyendo por completo).
  2. Cree una nueva base de datos con estadísticas automáticas desactivadas. Script y recrear todas las tablas de la base de datos de origen. Use bcp para exportar / importar los datos a la nueva base de datos, en orden de clave de clúster. Script y recrear todos los índices. Vuelva a calcular todas las estadísticas con escaneo completo.
  3. Cree una nueva base de datos con estadísticas automáticas desactivadas. Script y recrear todas las tablas de la base de datos de origen. Use SSIS o T-SQL para transferir datos a la nueva base de datos. Script y recrear todos los índices. Vuelva a calcular todas las estadísticas con escaneo completo.

El paso final en todos los casos sería configurar la base de datos en modo de solo lectura.

¿Qué otras buenas / mejores opciones hay para hacer esto? Mi preocupación es trasladar los datos de tal manera que conserve un factor de relleno alto y de una manera lógicamente contigua.

Editar:

Debo mencionar que alrededor del 75% de los datos parecen estar almacenados en columnas de imagen (LOB).


3
¿Le importa (o la aplicación) si las tablas terminan físicamente en un grupo de archivos distinto PRIMARY?
Jon Seigel

@ JonSeigel Supongo que no, y en realidad es una muy buena idea, ya que me ahorraría la molestia de tener que crear una base de datos de plantilla y mover todos los datos.
db2

¿Está considerando solo soluciones que codifique usted mismo o también puede revisar alguna aplicación para ayudarlo con eso? Puede usar SQL Storage Compress de RedGate para comprimir datos en vivo. O puede intentar la Restauración virtual para hacer que las copias de seguridad comprimidas estén disponibles como dbs en línea (sin tener realmente el espacio completo necesario). Todos están basados ​​en el antiguo controlador de archivos de Windows Hyperbac, que son muy buenos para comprimir datos en vivo y copias de seguridad.
Marian

@ Marian Suena interesante, pero me gustaría seguir con las capacidades nativas de SQL Server por ahora. Solo necesito desfragmentar de manera muy efectiva las bases de datos, sin que quede mucho espacio sin usar en los archivos. Si se trata de una herramienta de terceros que realiza el trabajo en lugar de crear scripts manualmente, está bien.
db2

Es solo una idea, pero ¿por qué no crear un nuevo grupo de archivos, agregar un archivo, establecer un crecimiento razonable (digamos 500 MB) y luego reconstruir sus tablas en ese nuevo grupo de archivos. Luego reduzca el archivo primario a casi nada. No le importará la fragmentación en las tablas del sistema.
Nic

Respuestas:


1

Para eliminar la fragmentación física en los archivos, puede mover el índice agrupado con la eliminación existente a un nuevo grupo de archivos. Como van a ser RO, haga que todos llenen el factor 100% ya que no se necesita espacio para inserciones, divisiones de página causadas por actualizaciones.

Esto también le permitiría realizar una restauración gradual y poner la base de datos en línea muy rápidamente si alguna vez decide ir a Enterprise. Enterprise también permite índices de almacén de columnas además de reducir masivamente el tiempo de consulta para estos datos de solo lectura, que es un filete masivo.

Puede usar la opción shrinkfile una vez antes de cambiar a lectura solo sin problemas serios con la fragmentación para eliminar el espacio al final del archivo como lo desee.

En una nota al margen, simplemente verificando que está utilizando los últimos tipos de datos para sus LOBS. es decir, nvarchar (max) o varchar (max) en lugar de ntext o text, varbinary (max) en lugar de image?


Utiliza principalmente texto e imagen, desafortunadamente. Es una aplicación de terceros, por lo que no tengo la capacidad de cambiar eso.
db2

@ es transparente para la aplicación realmente, con el servidor SQL almacenando la información en fila si <8k. Si el proveedor dice que no es compatible, les preguntaría por qué todavía están utilizando tipos de datos originalmente desaprobados en SQL Server 2005.
DamagedGoods

No puedo estar totalmente seguro de que la aplicación no haga cosas específicas de texto / imagen como WRITETEXT que fallarían después de cambiar el tipo de datos. Pero volviendo al punto principal, parece que recrear el índice agrupado en realidad no moverá los datos LOB con él.
db2

puede hacer esto, pero debe ir al diseñador en la GUI, luego expandir las propiedades, luego tiene un 'espacio de datos regular' pero también un grupo de archivos TEXTIMAGE, cambiando esto, ¡pero tenga cuidado de que esto vuelva a crear la tabla! obviamente puede escribir esto y ejecutarlo en una ventana de mantenimiento si es posible
DamagedGoods

Entendido, esa podría ser una forma útil de generar los scripts de reconstrucción apropiados, como mínimo.
db2

0

Enfrenté un problema similar con una herramienta de terceros que también estaba usando un tipo de datos de imagen para almacenar datos no estructurados, y lo resolví convirtiendo la columna para usar filestream . Deberá realizar algunas pruebas para asegurarse de que la aplicación siga funcionando como espera, pero esto le dará la capacidad de escribir su propio proceso de archivo que mueva sus datos a un archivo db de manera eficiente.


Sospecho que filestream no se escalaría bien en este caso. Tenemos más de 14 millones de filas en 17 bases de datos, y estamos obteniendo mensajes a alrededor de 15,000 por día. Una parte sustancial de los cuerpos de los mensajes están por debajo de 4 KB, por lo que el desperdicio de clúster NTFS probablemente sería brutal (y eso incluso si agregamos un nuevo volumen de disco con un tamaño de bloque inferior a 64 KB).
db2

En ese caso, ¿puede convertir el tipo de datos a algo como nvarchar (max) y usar la cláusula TEXTIMAGE_ON para especificar un grupo de archivos diferente para estos objetos grandes? Eso le permitirá almacenar los datos fuera de fila y le permitirá crear su propio proceso para administrar el archivado.
Liam Confrey

el uso de filestream realmente depende de qué tan grande sea cada LOBS. Creo que> 1 MB por registro a tener en cuenta. Así que estoy de acuerdo en este caso, no es una opción
DamagedGoods
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.