¿Hay alguna forma confiable de determinar cuándo debe ejecutar DBCC CLEANTABLE para recuperar espacio?

11

Últimamente, en lugar de solo aumentar los archivos cuando se acercan al 80% de utilización de archivos, he sido más proactivo en reclamar espacio a través de los trucos habituales como desfragmentar montones, agregar y soltar índices agrupados, implementar la compresión de filas o páginas, etc.

Sin embargo, hay algunos casos en los que pude recuperar aún más espacio ejecutando DBCC CLEANTABLE . Con cientos de bases de datos en mi entorno, no es posible saber qué hacen los usuarios en cada una y es completamente aceptable que haya cambios que impliquen la caída de columnas de longitud fija. Por lo general, he encontrado estas oportunidades mirando los recuentos de filas frente a los recuentos de páginas en algunos scripts de utilización de espacio de objetos que he escrito. Me gustaría llevar esto un paso más allá al intentar automatizar la detección de este tipo de escenarios.

Lo que me gustaría saber es si alguien por ahí está monitoreando activamente este tipo de oportunidades y, de ser así, ¿qué buscas específicamente?

Mis pensamientos fueron escribir algo en la línea de reunir el tamaño máximo y mínimo de una fila, el número de filas en la tabla, el número de páginas asignadas y el número de páginas utilizadas, y luego hacer algunas matemáticas básicas para registrar resultados que están bien fuera de lo que se "esperaría".

AndrewSQL
fuente
Recomiendo usar el parámetro batch_size en tablas grandes. Esto hará que el comando se ejecute en una serie de transacciones en lugar de una transacción gigante.
datagod 01 de

Respuestas:

11

La solución que pensaría para este problema es ejecutar semanalmente un trabajo que ejecutará sp_spaceused para todas las tablas de una base de datos y guardar estos datos en una tabla. Si hay diferencias de tamaño para cada tabla mayor que ... digamos ... 10%, ejecutaría el dbcc limpiable.

Mi código para recorrer los tamaños de tabla se ve así:

if OBJECT_ID ('tempdb.dbo.#temp') is not null
    drop table #temp;

if OBJECT_ID ('dbo.BigTables') is not null
    drop table dbo.BigTables;
go

CREATE TABLE [dbo].[BigTables] (
    [table_name] [sysname] NOT NULL,
    [row_count] [int] NULL,
    [col_count] [int] NULL,
    [data_size] [varchar](50) NULL,
    [Date] [datetime] NOT NULL,
    [DBName] [nvarchar](128) NULL
);
GO

CREATE TABLE #temp (
    table_name sysname ,
    row_count int,
    reserved_size varchar(50),
    data_size varchar(50),
    index_size varchar(50),
    unused_size varchar(50)
);
go

INSERT     #temp
EXEC       sp_msforeachtable 'sp_spaceused ''?'''

insert into dbo.BigTables
SELECT     a.table_name,
           a.row_count,
           count(*) as col_count,
           a.data_size,
           getdate() as [Date],
    'MY DB' as DBName
FROM       #temp a
INNER JOIN information_schema.columns b
           ON a.table_name collate database_default
                = b.table_name collate database_default
GROUP BY   a.table_name, a.row_count, a.data_size
ORDER BY   CAST(Replace(a.data_size, ' KB', '') as integer) desc

DROP TABLE #temp;

Select * from dbo.BigTables;

Ahora solo necesita construir la lógica que verificará cuál sería el cambio de tamaño durante la semana y lo programará.

Mariana
fuente
Ahora, si hay razones para sospechar imprecisiones en los informes de tamaño de la tabla, debe ir a DBCC UPDATEUSAGE (esto solucionará los recuentos de filas y páginas). ¡Me alegra ser de ayuda!
Marian