patternsqlMajor
Query to report disk space allocation and used space
Viewed 0 times
spacediskusedqueryreportandallocation
Problem
We are using 6 databases in total for an application, and we can only share 4TB of space among all 6 auto-grow databases (via SAN storage).
I'd like to write a query (report) for a single database indicating the "Currently allocated space" and "Available free space" attributes under the Tasks > Shrink > Database option in SQL Server Management Studio.
Then I'd like to convert those numbers to TB and total each database to get a rough estimate of how much space we have left. Can these fields be accessed via a T-SQL query? If so, what would the query look like?
I'd like to write a query (report) for a single database indicating the "Currently allocated space" and "Available free space" attributes under the Tasks > Shrink > Database option in SQL Server Management Studio.
Then I'd like to convert those numbers to TB and total each database to get a rough estimate of how much space we have left. Can these fields be accessed via a T-SQL query? If so, what would the query look like?
Solution
Here is the query Management Studio uses to populate those numbers:
You need to perform math here just like Management Studio does in order to get the same numbers. Also, the left join to
With this update, assuming your database doesn't change in the meantime, it should yield:
Doing some simple math, and isolating just the three numbers you want:
SELECT
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
SUM(a.total_pages) AS [SpaceUsed],
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM
sys.partitions p join sys.allocation_units a
on p.partition_id = a.container_id
left join sys.internal_tables it
on p.object_id = it.object_idYou need to perform math here just like Management Studio does in order to get the same numbers. Also, the left join to
sys.internal_tables seems superfluous at best. So adjusting that query to match your ideal output:SELECT
(SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
CONVERT(DECIMAL(18,2), SUM(a.total_pages)*8/1024.0) AS [SpaceUsed],
(SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM sys.partitions p join sys.allocation_units a
on p.partition_id = a.container_id;With this update, assuming your database doesn't change in the meantime, it should yield:
753475.94 744030.07 2900.00Doing some simple math, and isolating just the three numbers you want:
;WITH t(s) AS
(
SELECT CONVERT(DECIMAL(18,2), SUM(size)*8/1024.0)
FROM sys.database_files
WHERE [type] % 2 = 0
),
d(s) AS
(
SELECT CONVERT(DECIMAL(18,2), SUM(total_pages)*8/1024.0)
FROM sys.partitions AS p
INNER JOIN sys.allocation_units AS a
ON p.[partition_id] = a.container_id
)
SELECT
Allocated_Space = t.s,
Available_Space = t.s - d.s,
[Available_%] = CONVERT(DECIMAL(5,2), (t.s - d.s)*100.0/t.s)
FROM t CROSS APPLY d;Code Snippets
SELECT
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
SUM(a.total_pages) AS [SpaceUsed],
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM
sys.partitions p join sys.allocation_units a
on p.partition_id = a.container_id
left join sys.internal_tables it
on p.object_id = it.object_idSELECT
(SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
CONVERT(DECIMAL(18,2), SUM(a.total_pages)*8/1024.0) AS [SpaceUsed],
(SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM sys.partitions p join sys.allocation_units a
on p.partition_id = a.container_id;753475.94 744030.07 2900.00;WITH t(s) AS
(
SELECT CONVERT(DECIMAL(18,2), SUM(size)*8/1024.0)
FROM sys.database_files
WHERE [type] % 2 = 0
),
d(s) AS
(
SELECT CONVERT(DECIMAL(18,2), SUM(total_pages)*8/1024.0)
FROM sys.partitions AS p
INNER JOIN sys.allocation_units AS a
ON p.[partition_id] = a.container_id
)
SELECT
Allocated_Space = t.s,
Available_Space = t.s - d.s,
[Available_%] = CONVERT(DECIMAL(5,2), (t.s - d.s)*100.0/t.s)
FROM t CROSS APPLY d;Context
StackExchange Database Administrators Q#29543, answer score: 43
Revisions (0)
No revisions yet.