是否有可靠的方法来确定何时应该运行 DBCC CLEANTABLE 来回收空间?

And*_*SQL 12 sql-server-2005 sql-server-2008 sql-server

最近,我不再只是在文件利用率接近 80% 时增加文件,而是更主动地通过常用技巧回收空间,例如对堆进行碎片整理、添加和删除聚集索引、实现行或页面压缩等。

但是,在某些情况下,我可以通过执行DBCC CLEANTABLE回收更多空间。我的环境中有数百个数据库,不可能知道用户在每个数据库中做了什么,并且完全可以接受涉及删除固定长度列的更改。我通常通过查看我编写的一些对象空间利用脚本中的行数与页数来发现这些机会。我想通过尝试自动检测这些场景来更进一步。

我想知道的是,是否有人在积极监控此类机会,如果是,您具体在寻找什么?

我的想法是写一些东西,收集一行的最大和最小大小、表中的行数、分配的页数和使用的页数,然后做一些基本的数学运算来记录结果远远超出了“预期”。

Mar*_*ian 12

对于这个问题,我想到的解决方案是每周运行一个作业,该作业将为数据库中的所有表运行sp_spaceused并将这些数据保存在一个表中。如果每个表的大小差异大于..10%,我将运行 dbcc cleantable。

我循环遍历表大小的代码如下所示:

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;
Run Code Online (Sandbox Code Playgroud)

现在您只需要构建逻辑来验证一周内的大小变化并安排它。