DBCC SHOWFILESTATS 是查看未使用空间的准确方法吗?

Jus*_*son 2 sql-server partitioning disk-space

我们有几个表,每个表都有近 1 亿行数据。一位同事将这些表设置为基于日期字段的分区。

我们的磁盘空间开始不足并且知道分区有自己的文件组,我想看看某些分区是否比它们需要的大并且正在咀嚼磁盘。

我运行了记录不佳的命令:

dbcc showfilestats
Run Code Online (Sandbox Code Playgroud)

这是输出的片段:

TotalExtents   UsedExtents   Name         FileName
363200         200701        LogJun2013   F:\SQL\DATA\logs_phyJun2013.ndf
812800         432127        LogJul2013   F:\SQL\DATA\logs_phyJul2013.ndf
718400         401500        LogAug2013   F:\SQL\DATA\logs_phyAug2013.ndf
1016983        555565        LogSep2013   F:\SQL\DATA\logs_phySep2013.ndf
Run Code Online (Sandbox Code Playgroud)

如果我正确理解这一点(IANADBA),考虑到大量未使用的范围,这些文件中有很多未使用的空间。此外,我们只收集新数据,因此我们永远不需要从 2013 年开始扩大这些旧分区。

我对此的理解是否正确?如果是这样,我该如何从这些文件中释放空间?

Mik*_*Fal 6

您可以使用sys.dm_db_index_physical_stats来确定分区的大小以及使用了多少空间。使用该page_count字段查看分区的大小。如果您执行 SAMPLED 或 DETAILED 扫描,您还将获得 的值avg_page_space_used_in_percent,这将允许您估计分区中实际使用了多少空间。

SELECT
    object_name(di.object_id) [table_name]
    ,i.name
    ,di.index_id
    ,di.partition_number
    ,di.record_count
    ,di.page_count/128.0 [partition_size_MB]
    ,di.avg_page_space_used_in_percent
    ,(di.page_count/128.0) * di.avg_page_space_used_in_percent * .01 [space_used_MB]
FROM
    sys.indexes i 
    join sys.dm_db_index_physical_stats(DB_ID(),object_id('<Table Name'>), NULL, NULL, 'SAMPLED') di 
      on i.object_id = di.object_id and i.index_id = di.index_id
Run Code Online (Sandbox Code Playgroud)

如果您想检查实际文件中的可用空间,我建议使用 Glenn Berry 的DMV 脚本中的查询。

SELECT f.name AS [File Name] , f.physical_name AS [Physical Name], 
CAST((f.size/128.0) AS DECIMAL(15,2)) AS [Total Size in MB],
CAST(f.size/128.0 - CAST(FILEPROPERTY(f.name, 'SpaceUsed') AS int)/128.0 AS DECIMAL(15,2)) 
AS [Available Space In MB], [file_id], fg.name AS [Filegroup Name]
FROM sys.database_files AS f WITH (NOLOCK) 
LEFT OUTER JOIN sys.data_spaces AS fg WITH (NOLOCK) 
ON f.data_space_id = fg.data_space_id OPTION (RECOMPILE);
Run Code Online (Sandbox Code Playgroud)

这应该让您大致了解您是否有任何空间可以回收。至于实际回收它,这取决于您需要做什么。如果您的文件只是过度配置,您可以使用 DBCC SHRINKFILE 缩小它们(这不是应该定期执行的操作)。但是,如果文件大部分已满,但分区中有可用空间,请尝试重建索引以回收一些空间(可能由于碎片而丢失)。如果磁盘已满且分区中没有空间,请考虑将数据归档到另一个磁盘系统或离线存储。

话虽如此,1 亿行确实不是那么多数据,我很好奇为什么选择分区作为解决方案。这是很多开销,对您没有很多好处。