正在检查SQL Server数据库文件中是否有未使用的空间

正在检查SQL Server数据库文件中是否有未使用的空间,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,我试图使用我在某处找到的这个稍微修改过的查询版本来确定SQL Server数据库文件中有多少可用空间 SELECT GETDATE() AS [Timestamp], [TYPE] = A.TYPE_DESC, [FILE_Name] = A.name, [FILESIZE_MB] = CONVERT(DECIMAL(10, 2), A.SIZE / 128.0), [USEDSPACE_MB] = CONVERT(DECIMAL(10, 2), A.SI

我试图使用我在某处找到的这个稍微修改过的查询版本来确定SQL Server数据库文件中有多少可用空间

SELECT
    GETDATE() AS [Timestamp],
    [TYPE] = A.TYPE_DESC,
    [FILE_Name] = A.name,
    [FILESIZE_MB] = CONVERT(DECIMAL(10, 2), A.SIZE / 128.0),
    [USEDSPACE_MB] = CONVERT(DECIMAL(10, 2), A.SIZE / 128.0 - ((SIZE / 128.0) - CAST(FILEPROPERTY(A.NAME, 'SPACEUSED') AS INT) / 128.0)),
    [FREESPACE_MB] = CONVERT(DECIMAL(10, 2), A.SIZE / 128.0 - CAST(FILEPROPERTY(A.NAME, 'SPACEUSED') AS INT) / 128.0),
    [FREESPACE_%] = CONVERT(DECIMAL(10, 2), ((A.SIZE / 128.0 - CAST(FILEPROPERTY(A.NAME, 'SPACEUSED') AS INT) / 128.0) / (A.SIZE / 128.0)) * 100),
    [FILEGROUP_NAME] = fg.name,
    [File_Location] = A.PHYSICAL_NAME
FROM
    sys.database_files A 
LEFT JOIN 
    sys.filegroups fg ON A.data_space_id = fg.data_space_id 
WHERE 
    A.TYPE_DESC NOT LIKE 'LOG'
ORDER BY 
    A.TYPE desc, A.NAME;
由于从数据库中删除数据时数据库文件不会收缩,因此查询并没有提供我要查找的所有信息

是否有任何方法可以告诉
SpaceUsed
文件属性中包含了多少实际数据(与删除的记录等导致的可用空间相比)?或者是执行类似于
DBCC SHRINKDATABASE
的操作并更改文件物理大小的唯一选项

我已经研究了
sp\u spaceused
sys.dm\u db\u index\u physical\u stats
,以及许多其他内容,但到目前为止还没有找到解决方案

更新:我发现了一些我认为更接近我需要的东西,尽管我不确定它是否正确。从使用的页面计数/平均页面空间计算使用的空间看起来更接近我的期望值

SELECT 
    page_count,
    avg_page_space_used_in_percent
FROM 
    sys.dm_db_index_physical_stats(db_id('TestDB'), NULL, NULL, NULL, 'Detailed')

在SSMS中,尝试右键单击数据库,转到“报告”,然后是“标准报告”,然后选择“磁盘使用情况”。如果这对你不起作用,也许其他标准报告之一会起作用

在标准光盘使用情况报告的饼图下方,您可以看到数据文件使用的光盘空间


在SSMS中,尝试右键单击数据库,转到“报告”,然后是“标准报告”,然后选择“磁盘使用情况”。如果这对你不起作用,也许其他标准报告之一会起作用

在标准光盘使用情况报告的饼图下方,您可以看到数据文件使用的光盘空间


有几种方法可以做到这一点,我个人最喜欢的是未记录的DBCC命令ShowFileStats。它输出数据库的数据文件列表、磁盘上的扩展数据块总数和实际使用的扩展数据块数

对于那些不记得的用户,数据块的大小为8页,而页面的大小为8KB。因此,对这两个输出进行一点计算,就可以得到所需的信息。下面是一个快速示例脚本

请注意,DBCC命令在当前数据库的上下文中运行。你可以修改它,把它变成一个小循环

IF OBJECT_ID('tempdb..#tempDataUsage') IS NOT NULL DROP TABLE #tempDataUsage
CREATE TABLE #tempDataUsage
(
    [Fileid] INT,
    [FileGroup] INT,
    [TotalExtents] BIGINT,
    [UsedExtents] BIGINT,
    [Name] sysname,
    [FileName] varchar(256)
)
DECLARE @SQLStatement NVARCHAR(400) = 'USE msdb
DBCC ShowFileStats'
INSERT INTO #tempDataUsage
EXEC (@SQLStatement)

SELECT 
    (TotalExtents * 8 * 8) AS totalSpaceOndiskKB,
    (UsedExtents * 8 * 8) AS SpaceActuallyUsedKB,
    Name AS DbName,
    FileName 
FROM 
    #tempDataUsage

有几种方法可以做到这一点,我个人最喜欢的是未记录的DBCC命令ShowFileStats。它输出数据库的数据文件列表、磁盘上的扩展数据块总数和实际使用的扩展数据块数

对于那些不记得的用户,数据块的大小为8页,而页面的大小为8KB。因此,对这两个输出进行一点计算,就可以得到所需的信息。下面是一个快速示例脚本

请注意,DBCC命令在当前数据库的上下文中运行。你可以修改它,把它变成一个小循环

IF OBJECT_ID('tempdb..#tempDataUsage') IS NOT NULL DROP TABLE #tempDataUsage
CREATE TABLE #tempDataUsage
(
    [Fileid] INT,
    [FileGroup] INT,
    [TotalExtents] BIGINT,
    [UsedExtents] BIGINT,
    [Name] sysname,
    [FileName] varchar(256)
)
DECLARE @SQLStatement NVARCHAR(400) = 'USE msdb
DBCC ShowFileStats'
INSERT INTO #tempDataUsage
EXEC (@SQLStatement)

SELECT 
    (TotalExtents * 8 * 8) AS totalSpaceOndiskKB,
    (UsedExtents * 8 * 8) AS SpaceActuallyUsedKB,
    Name AS DbName,
    FileName 
FROM 
    #tempDataUsage

谢谢你的信息。这基本上是我从查询中得到的同一类型的东西,所以它不完全符合我的要求。我不确定我想要的是否可能。谢谢你提供的信息。这基本上是我从查询中得到的同一类型的东西,所以它不完全符合我的要求。我不确定我想要的是否可能。这返回的信息与我使用的查询基本相同。我已经用另一种方法更新了这个问题,我发现这种方法看起来很有希望。@thephez是的,DMV可以工作。很抱歉,我没有听到“实际数据”的评论。您可能需要对数据库_Id进行分组,以获得真实的总数。看起来dmv会返回每个对象的结果。但是,如果您只是查看每个数据文件,我仍然更喜欢ShowFilestats.:)这将返回与我使用的查询基本相同的信息。我已经用另一种方法更新了这个问题,我发现这种方法看起来很有希望。@thephez是的,DMV可以工作。很抱歉,我没有听到“实际数据”的评论。您可能需要对数据库_Id进行分组,以获得真实的总数。看起来dmv会返回每个对象的结果。但是,如果您只是查看每个数据文件,我仍然更喜欢ShowFilestats.:)