I have MS SQL 2008 R2, 500 databases. What is the most efficient, easiest and \'modern\' way to query all databases sizes.
The output should have columns:
All seem overly complicated! Or am I missing something?
Surely all you need is something like:
select d.name, case when m.type = 0 then 'Data' else 'Log' end, m.size * 8 / 1024
from sys.master_files m JOIN sys.databases d ON d.database_id = m.database_id
or if you don't want the log:
select d.name, m.size * 8 / 1024
from sys.master_files m JOIN sys.databases d ON d.database_id = m.database_id and m.type =0
A better and quite simpler one
SELECT [Database Name] = DB_NAME(database_id),
[Type] = CASE WHEN Type_Desc = 'ROWS' THEN 'Data File(s)'
WHEN Type_Desc = 'LOG' THEN 'Log File(s)'
ELSE Type_Desc END,
[Size in MB] = CAST( ((SUM(Size)* 8) / 1024.0) AS DECIMAL(18,2) )
FROM sys.master_files
--Uncomment if you need to query for a particular database
--WHERE database_id = DB_ID(‘Database Name’)
GROUP BY GROUPING SETS
(
(DB_NAME(database_id), Type_Desc),
(DB_NAME(database_id))
) ORDER BY DB_NAME(database_id), Type_Desc DESC
It will give you size of Data File(s) and Log File(s) separately like below
DatabaseName Type Size in MB
-------------------------------------------
FMS Data File(s) 23.00
FMS Log File(s) 1.50
PointOfSale Data File(s) 4.00
PointOfSale Log File(s) 1.25
Union2 Data File(s) 336.00
Union2 Log File(s) 1191.13
SurveyProject Data File(s) 4.00
SurveyProject Log File(s) 1.00
Here's a simple, quick and reliable query that will give all database and log file names, sizes and also database statuses (e.g. ONLINE) in a nice, easy to read output:
SELECT
D.name,
F.Name AS FileType,
F.physical_name AS PhysicalFile,
F.state_desc AS OnlineStatus,
CAST(F.size AS bigint) * 8*1024 AS SizeInBytes,
CAST((F.size*8.0)/1024/1024 AS decimal(18,3)) AS SizeInGB
FROM
sys.master_files F
INNER JOIN sys.databases D ON D.database_id = F.database_id
ORDER BY SizeInBytes desc
I recently came across this page looking for something like this. Just in case someone comes across this and is interested in only the core user databases, you can use something like this which excludes Master, msdb...
SELECT
DB_NAME(db.database_id) DatabaseName,
(CAST(mfrows.RowSize AS FLOAT)*8)/1024 RowSizeMB,
(CAST(mflog.LogSize AS FLOAT)*8)/1024 LogSizeMB
FROM sys.databases db
LEFT JOIN (SELECT database_id, SUM(size) RowSize FROM sys.master_files WHERE type = 0 GROUP BY database_id, type) mfrows ON mfrows.database_id = db.database_id
LEFT JOIN (SELECT database_id, SUM(size) LogSize FROM sys.master_files WHERE type = 1 GROUP BY database_id, type) mflog ON mflog.database_id = db.database_id
where DB_NAME(db.database_id) not like 'master'
and DB_NAME(db.database_id) not like 'msdb'
and DB_NAME(db.database_id) not like 'model'
and DB_NAME(db.database_id) not like 'tempdb'
and DB_NAME(db.database_id) not like 'Northwind'
and DB_NAME(db.database_id) not like 'ReportServer'
order by DB_NAME(db.database_id)
sometimes SECURITY issues prevent from asking for all the db's and you need to query one by one with the db prefix, for those cases i created this dynamic query
go
declare @Results table ([Name] nvarchar(max), [DataFileSizeMB] int, [LogFileSizeMB] int);
declare @QaQuery nvarchar(max)
declare @name nvarchar(max)
declare MY_CURSOR cursor
local static read_only forward_only
for
select name from master.dbo.sysdatabases where name not in ('master', 'tempdb', 'model', 'msdb', 'rdsadmin');
open MY_CURSOR
fetch next from MY_CURSOR into @name
while @@FETCH_STATUS = 0
begin
if(len(@name)>0)
begin
print @name + ' Column Exist'
set @QaQuery = N'select
'''+@name+''' as Name
,sum(case when type = 0 then size else 0 end) as DataFileSizeMB
,sum(case when type = 1 then size else 0 end) as LogFileSizeMB
from ['+@name+'].sys.database_files
group by replace(name, ''_log'', '''')';
insert @Results exec sp_executesql @QaQuery;
end
fetch next from MY_CURSOR into @name
end
close MY_CURSOR
deallocate MY_CURSOR
select * from @Results order by DataFileSizeMB desc
go
with fs
as
(
select database_id, type, size * 8.0 / 1024 size
from sys.master_files
)
select
name,
(select sum(size) from fs where type = 0 and fs.database_id = db.database_id) DataFileSizeMB,
(select sum(size) from fs where type = 1 and fs.database_id = db.database_id) LogFileSizeMB
from sys.databases db