There are two scripts I like to use to look at the file sizes on servers. The first one is everything I could hope for on servers where there is only a single file per filegroup. All of the vital information is all in one place. I know, DBAs tend to be good at math and there was no need for me to make all of these columns. However, any room I leave to demonstrate my mathematical powers in a professional environment…. Ok, look, CPU time is cheap anymore, I’ll go with that for my reasoning.
IF Object_ID('TempDB..##FileSize') IS NOT NULL BEGIN DROP TABLE ##FileSize END CREATE TABLE ##FileSize ( DB VarChar(128) , FileLogicalName VarChar(128) , FilePhysicalName VarChar(512) , FileGroup VarChar(128) , Used_MB VarChar(128) , Free_MB VarChar(128) , Size_MB VarChar(128) , GrowthRate VarChar(128) , MaxSize VarChar(128) ) exec sp_MSforeachdb N'use [?]; INSERT INTO ##FileSize SELECT DB = db_name() , FileLogicalName = f.name , FilePhysicalName = f.physical_name , FileGroup = ISNULL(g.name, f.Type_Desc) , Used_MB = REPLACE(CONVERT(varchar(100), (CAST((FileProperty(f.name, ''SpaceUsed'')) / 128 AS money)), 1), ''.00'', '''') , Free_MB = REPLACE(CONVERT(varchar(100), (CAST((f.size - FileProperty(f.name, ''SpaceUsed'')) / 128 AS money)), 1), ''.00'', '''') , Size_MB = REPLACE(CONVERT(varchar(100), (CAST((f.size) / 128 AS money)), 1), ''.00'', '''') , GrowthRate = Case Is_Percent_Growth WHEN 1 THEN '''' + Cast(Growth as VarChar(100)) + ''%'' ELSE REPLACE(CONVERT(varchar(100), (CAST(Growth/128 AS money)), 1), ''.00'', '''') + '' MB'' END , MaxSize = Case Max_Size WHEN -1 THEN ''---'' WHEN 268435456 THEN ''---'' ELSE REPLACE(CONVERT(varchar(100), (CAST(Max_Size/128 AS money)), 1), ''.00'', '''') + '' MB'' END FROM sys.database_files f LEFT JOIN sys.filegroups g on f.data_space_id = g.data_space_id ' SELECT * , PctUsed = Cast(100 * replace(Used_MB, ',', '') / (Cast(replace(Size_MB,',', '') as Dec(20,2)) + .01) as Dec(20,2)) --, PctFree = 100 - Cast(100 * replace(Used_MB, ',', '') / (Cast(replace(Size_MB,',', '') as Dec(20,2)) + .01) as Dec(20,2)) FROM ##FileSize --WHERE DB = 'msdb' ORDER BY FilePhysicalName DROP TABLE ##FileSize
The problem with that script is that there are times it makes sense to have multiple files in a filegroup. Be it disk limitations, best practices on a SAN saying not to extend a LUN, or your predecessor tossed logic to the wind, there are many reasons you could have multiple files where the previous script leaves you doing math to figure out how big the filegroup is or how much room for growth you have. You know what I said about doing math…CPU time is cheap. Here’s what I use when I need to see the filegroup sizes.
IF Object_ID('TempDB..##FileGroupSize') IS NOT NULL BEGIN DROP TABLE ##FileGroupSize END CREATE TABLE ##FileGroupSize ( DB VarChar(128) , FileGroup VarChar(128) , Used_MB Int , Free_MB Int , Size_MB Int ) exec sp_MSforeachdb N'use [?]; INSERT INTO ##FileGroupSize SELECT DB = db_name() , FileGroup = ISNULL(g.name, f.Type_Desc) , Used_MB = SUM(FileProperty(f.name, ''SpaceUsed'')) / 128 , Free_MB = SUM(f.size - FileProperty(f.name, ''SpaceUsed'')) / 128 , Size_MB = SUM(f.size) / 128 FROM sys.database_files f LEFT JOIN sys.filegroups g on f.data_space_id = g.data_space_id GROUP BY f.Type_Desc, g.name ' SELECT * , PctUsed = Cast(100 * Used_MB / (Cast(Size_MB as Dec(20,2)) + .01) as Dec(20,2)) , PctFree = 100 - Cast(100 * Used_MB / (Cast(Size_MB as Dec(20,2)) + .01) as Dec(20,2)) FROM ##FileGroupSize ORDER BY DB, FileGroup DROP TABLE ##FileGroupSize
It should be noted that I have different rules for different situations. If a script is part of a stored proc or view then * isn’t even a consideration. If an external program, even an SSRS report, will consume the code then I would never try to format it using SQL. However, these are saved in my scripts folder as FileSize.sql and FilegroupSizes.sql, and my personal .sql files get to break a rule or two.
Filed under: File Sizes, Scripts, SQL Server Tagged: File, File Management, File Size, Filegroup, sp_MSforeachdb, sys.database_files, sys.filegroups