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


11

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

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

我想知道的是,是否有人在积极监视这些机会,如果是,您在寻找什么?

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


我强烈建议在大型表上使用batch_size参数。这将导致命令在一系列事务中运行,而不是一个巨型事务。
datagod 2015年

Answers:


11

我想到的解决方案是每周运行一个作业,该作业将对数据库中的所有表运行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;

现在,您只需要构建逻辑即可验证一周中尺寸的变化并将其调度。


现在,如果有理由怀疑表大小报告中的不正确之处,则应该进行DBCC UPDATEUSAGE(这将修复行和页数)。很高兴有帮助!
玛丽安
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.