数据库可用空间的计算

--> Title : 数据库可用空间的计算

--> Author : wufeng4552

--> Date : 2011-01-12

数据库管理员的一个职能就是留意数据库和数据库文件内的空闲空间。自动增长功能作为最后一种手段是很好的,但是主动管理数据库文件是一种更好的方法。如果在文件中有很多的空闲空间,那么这些信息也可以在需要时用来压缩文件。

这里有几点需要提示:

1):随着数据库的不断填充,它的空间也在不断的增长。

2):数据库自动增长时,不会需要多少增多少,一般情况会留出额外的空间

3):如果数据被删除了,则不会自动将空间释放,占用的空间也会一直保留在数据文件中

有几种方法可以查询可用空间

方法一:

use db_sunrise

go

sp_spaceused

/*

database_name database_size unallocated space

---------------------------------------------------------

db_Sunrise 1410.50 MB 376.93 MB

reserved data index_size unused

------------------ ------------------ ------------------

986120 KB 740096 KB 236216 KB 9808 KB

*/

go

sp_spaceused @updateusage = 'TRUE '

sp_spaceused @updateusage = 'TRUE '

/*

database_name database_size unallocated space

---------------------------------------------------

db_Sunrise 1410.50 MB 377.05 MB

reserved data index_size unused

------------------ ------------------ ------------------

986056 KB 740096 KB 236024 KB 9936 KB

*/方法二:

DBCC SQLPERF

这个命令会为你提供每个数据库中日志文件的输出结果。这个命令也会为你提供累计信息,因此如果你有多个日志文件,那么它会提供给你每个数据库所有日志文件的总空闲空间。

DBCC SQLPERF(logspace)

/*

Database Name Log Size (MB) Log Space Used (%) Status

------------------------------------------------------

db_Sunrise 70.55469 96.74316 0

db_Kcgl 1030.992 99.3326 0

*/

方法三:FILEPROPERTY

另一个选项是使用FILEPROPERTY函数的SpaceUsed属性,它将告诉我们使用了多少空间,然后我们可以基于当前的大小来计算可用空间

SELECT DB_NAME() AS DbName,

name AS FileName,

size/128.0 AS CurrentSizeMB,

size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT)/128.0

AS FreeSpaceMB

FROM sys.database_files;

/*

DbName FileName CurrentSizeMB FreeSpaceMB

--------------------------------------------------------

db_Sunrise db_Sunrise 976.375000 281.312500

db_Sunrise db_Sunrise_log 70.562500 2.289063

db_Sunrise db_Sunrise_1 363.562500 94.687500

*/

<think>好的,用户现在想要查询MSSQL中所有数据库的占用空间可用空间大小。之前我已经给过两种方法,一种是使用sp_spaceused和sp_msforeachdb存储过程,另一种是使用sys.master_files系统视图。现在用户再次提问,需要结合他们提供的引用内容来优化回答。 首先,查看用户提供的引用内容。引用1提到了使用sp_spaceused来查看单个表的空间,但用户现在需要所有数据库的信息。引用2和引用3分别展示了不同方法查询数据库和表的空间使用情况,其中引用2用的是sys.database_files,而引用3是information_schema.tables,但后者可能只适用于某些数据库系统,比如MySQL,而不是MSSQL,需要确认。 用户的需求是获取所有数据库的总占用空间可用空间,而不是单个数据库或表。之前的回答已经覆盖了这一点,但可能需要更详细或结合引用中的某些方法。例如,用户可能希望同时看到数据库级别的汇总和文件级别的详细信息,或者需要更精确的计算方式。 另外,用户可能对日志文件的空间占用有疑问,因为在之前的回答中提到sys.master_files方法中FILEPROPERTY不包含日志文件的使用量。需要确保回答中明确区分数据和日志文件的空间计算。 现在需要整合引用中的有用信息。例如,引用2中的查询可以调整用于所有数据库,但需要遍历每个数据库。而引用3中的方法可能不适用于MSSQL,所以可能需要忽略或指出差异。 可能的解决方案是增强之前的脚本,结合sp_spaceused和sys.master_files,同时处理数据和日志文件的空间计算。或者,提供一个更全面的查询,将每个数据库的数据和日志文件分开统计,再汇总总和。 需要注意的是,用户可能希望脚本直接执行,不需要手动切换数据库,因此使用动态SQL或者系统视图来跨数据库查询会更合适。同时,确保排除系统数据库,如database_id >4。 可能还需要处理单位转换,例如将页转换为MB,以及处理不同文件的类型(数据文件是ROWS,日志是LOG)。在计算总占用空间时,需要分别汇总数据和日志文件的空间使用情况,因为sp_spaceused可能不包括日志,而sys.master_files可以获取所有文件的信息。 总结,需要提供一个能够遍历所有数据库,汇总每个数据库的总大小、已用空间和剩余空间的查询,同时确保数据和日志文件都被正确计算。可能需要使用动态SQL来执行每个数据库中的sp_spaceused,或者通过sys.master_files和FILEPROPERTY来获取精确数值,并处理日志文件的特殊情况。</think>根据您的需求和站内相关技术参考,以下是三种经过优化的完整解决方案,包含数据库级和文件级的空间分析: ### 方法1:增强型存储过程遍历(数据库级汇总) ```sql CREATE TABLE #DBStats ( database_name NVARCHAR(128), database_size DECIMAL(10,2), unallocated_space DECIMAL(10,2) ) DECLARE @cmd NVARCHAR(MAX) = ' USE [?]; INSERT INTO #DBStats SELECT DB_NAME() AS database_name, CAST(REPLACE(database_size, '' MB'','''') AS DECIMAL(10,2)), CAST(REPLACE(unallocated_space, '' MB'','''') AS DECIMAL(10,2)) FROM (EXEC sp_spaceused) AS sp' EXEC sp_msforeachdb @cmd SELECT database_name, database_size AS [总空间(MB)], database_size - unallocated_space AS [已用空间(MB)], unallocated_space AS [可用空间(MB)], CONVERT(VARCHAR, ROUND((database_size - unallocated_space)/database_size*100,2)) + '%' AS [使用率] FROM #DBStats WHERE database_name NOT IN ('master','model','msdb','tempdb') ORDER BY database_size DESC DROP TABLE #DBStats ``` 说明:此方法通过改进数据转换逻辑,增加使用率百分比,适用于快速查看所有用户数据库空间概况[^1][^2] ### 方法2:精确文件级分析(含日志文件) ```sql SELECT DB_NAME(mf.database_id) AS [数据库], SUM(CASE WHEN type_desc = 'ROWS' THEN mf.size/128.0 END) AS [数据文件总分配空间(MB)], SUM(CASE WHEN type_desc = 'ROWS' THEN FILEPROPERTY(name,'SpaceUsed')/128.0 END) AS [数据文件已用空间(MB)], SUM(CASE WHEN type_desc = 'LOG' THEN mf.size/128.0 END) AS [日志文件总分配空间(MB)], SUM(CASE WHEN type_desc = 'LOG' THEN mf.size/128.0 - (mf.size/128.0 - FILEPROPERTY(name,'SpaceUsed')/128.0) END) AS [日志文件已用空间(MB)] FROM sys.master_files mf WHERE mf.database_id > 4 GROUP BY DB_NAME(mf.database_id) ``` 说明:此方案通过`sys.master_files`视图,分别统计数据文件(ROWS)和日志文件(LOG)的空间使用情况,其中日志文件使用`size - (size - SpaceUsed)`的特殊计算方式[^2][^3] ### 方法3:动态SQL综合查询(含收缩建议) ```sql DECLARE @Results TABLE ( DBName NVARCHAR(128), TotalSizeMB DECIMAL(15,2), UsedMB DECIMAL(15,2), FreeMB DECIMAL(15,2), DataFiles INT, LogFiles INT ) DECLARE @SQL NVARCHAR(MAX) = ' USE [?]; INSERT INTO @Results SELECT DB_NAME(), SUM(size/128.0), SUM(FILEPROPERTY(name,''SpaceUsed'')/128.0), SUM((size - FILEPROPERTY(name,''SpaceUsed''))/128.0), SUM(CASE WHEN type = 0 THEN 1 ELSE 0 END), SUM(CASE WHEN type = 1 THEN 1 ELSE 0 END) FROM sys.database_files' INSERT INTO @Results EXEC sp_msforeachdb @SQL SELECT DBName AS [数据库名称], TotalSizeMB AS [总空间(MB)], UsedMB AS [已用空间(MB)], FreeMB AS [可用空间(MB)], CONVERT(VARCHAR, ROUND((UsedMB/TotalSizeMB)*100,2)) + '%' AS [使用率], CASE WHEN FreeMB > TotalSizeMB*0.3 THEN '建议收缩' ELSE '正常' END AS [空间建议], DataFiles AS [数据文件数], LogFiles AS [日志文件数] FROM @Results WHERE DBName NOT IN ('master','model','msdb','tempdb') ORDER BY TotalSizeMB DESC ``` 说明:此动态查询可显示文件分布情况,并基于可用空间超过30%时给出收缩建议[^2][^3] **三种方法的对比分析:** 1. 方法1适合快速概览,但日志空间计算不精确 2. 方法2提供最准确的文件级分析,区分数据和日志空间 3. 方法3包含智能建议,适合日常维护 4. 所有方法均排除系统数据库(`database_id >4`) 建议生产环境优先使用方法2进行精确分析,结合方法3的收缩建议进行空间优化。如需监控空间趋势,可定期运行这些脚本并将结果存入历史表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值