SQL Server Space Usage

SQL Server Space Usage

SQL Server Space Usage

Hello there, this post can explain various ways to know the SQL Server Space Usage information. Here are the different ways available:

  • XP_FIXEDDRIVES
  • SP_SPACEUSED
  • SP_HELPDB
  • DBCC SQLPERF (LOGSPACE)
  • sys.dm_os_volume_stats
  • Database and file wise Space usage
  • Used Space and Free Space For a given Database
  • Table wise space usage in a given database
  • Using SSMS Standard Reports
  • XP_CMDSHELL
  • PowerShell Script

XP_FIXEDDRIVES:

This is simple and straight method when we think of SQL Server Space Usage. It gets the drive free space information.

But we can’t know the Total Drive space, let’s say D drive is having 100 GB in which 60 GB is used and 40 GB is free then this command can only get us the free space information 40 GB.

/*********************************/
/**** Diskspace Report ***********/
/**** Tested: 2005, 2008, ********/
/**** 2008 R2, 2012, 2014, 2016 **/
/*********************************/
EXEC XP_FIXEDDRIVES;

SP_SPACEUSED

This can quickly get the Database and table space information. For database it captures total size, un-allocated space, data and index space details. For a given table it captures the total number of rows, reserved space, Data, Index and unused space information.

/*********************************************/
/**** Database & Table Space Usage ***********/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
-- To capture the Database Space information
EXEC SP_SPACEUSED;

-- To capture the given table Space information
SP_SPACEUSED '[SCHEMA].[TABLE]';

 

SP_HELPDB:

It’s one of the best handy commands which can quickly captures all databases space and other information from the given SQL Server instance. It gets the database name, total size, owner, current status and compatibility level etc. Also this system stored procedure can be used for a specific database where it can get more useful information about the given database including the physical file path and file size.

/*********************************************/
/**** Database space and other information ***/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
--Capture All databases information from the SQL instance
EXEC SP_HELPDB;

--Capture the given database information 
EXEC SP_HELPDB 'Master';

 

DBCC SQLPERF (LOGSPACE):

This is the quickest way to check the log usage for all databases in the instance. It captures log size, space used percentage and status.

/**************************************************/
/**** Log Space Usage Report for All databases*****/
/**** Tested: 2008, 2008 R2 ***********************/
/****	      2012, 2014, 2016 ********************/
/**************************************************/
DBCC SQLPERF(LOGSPACE);

 

sys.dm_os_volume_stats:

When we use XP_FIXEDDRIVES we can’t capture only the free space information, to get the total drive space information we can get it using “sys.dm_os_volume_stats”. Disk space details retrieved when only the drives containing any Database files from this instance. Let’s say the OS is attached the drives C, D, E, H and T. And no data or log file are located on C and H drive then the below query couldn’t get the C & H drive information rather it can capture the total and free space information from remaining drives.

/*********************************************/
/**** Drive Total and Free space info ********/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
SELECT	[Total(GB)],
		[FreeSpace(GB)],
		CAST(([FreeSpace(GB)]*100)/[Total(GB)] AS DECIMAL(15,2)) AS [%FreeSpace]
FROM
	(SELECT DISTINCT
			OVS.volume_mount_point [Drive],
			CAST(OVS.total_bytes / 1073741824 AS DECIMAL(15,2)) [Total(GB)],
			CAST(OVS.available_bytes / 1073741824 AS DECIMAL(15,2)) [FreeSpace(GB)]
	FROM	sys.master_files SMF
			CROSS APPLY sys.dm_os_volume_stats(SMF.database_id, SMF.[file_id]) OVS
	) AS Result;

 

Database and File wise Space Usage:

Here is the query to get database and the individual file (Data and Log) wise space usage information.

/*********************************************/
/**** Data and Log file wise Disk Usage ******/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
-- Data and Log file wise space usage for all databases
SELECT      D.name AS 'DB_Name',
			CASE WHEN MF.[Type] = 0 THEN 'DATA' ELSE 'LOG' END AS 'File_Type',
			MF.Name as 'File_Name',
            CAST((SUM(size)*8)/1024.00 AS DECIMAL(15,2)) AS [Disk_Space(MB)],
            CAST((SUM(size)*8)/(1024.00 * 1024.00) AS DECIMAL(15,2)) AS [Disk_Space(GB)]
FROM        sys.databases D
JOIN        sys.master_files MF
ON          D.database_id=MF.database_id
GROUP BY    D.name,MF.Name,MF.Type
ORDER BY    D.name,MF.Name,MF.Type;

-- Database wise  total disk usage in a given instance
SELECT      D.name AS 'DB_Name',
            CAST((SUM(size)*8)/1024.00 AS DECIMAL(15,2)) AS [Total_Disk_Space(MB)],
            CAST((SUM(size)*8)/(1024.00 * 1024.00) AS DECIMAL(15,2)) AS [Total_Disk_Space(GB)]
FROM        sys.databases D
JOIN        sys.master_files MF
ON          D.database_id=MF.database_id
GROUP BY    D.name
ORDER BY    D.name;

 

Used Space and Free Space For a given Database:

The most common situation is to identifying the available free space for a given single database. The below query can help you in identifying the percentage free space in a given database.

/**************************************************/
/**** For a given database used and free space ****/
/**** Tested: 2008, 2008 R2 ***********************/
/****		  2012, 2014, 2016 ********************/
/**************************************************/
SELECT 
	[Database], 
	[File_Name], 
	[FileGroup_Name],
	File_Path,
	[Total_Space(MB)],
	[Available_Space(MB)],
	CAST([Total_Space(MB)]/1024 AS DECIMAL(15,2)) AS [Total_Space(GB)],
	CAST([Available_Space(MB)]/1024 AS DECIMAL(15,2)) AS [Available_Space(GB)],
	CAST(([Available_Space(MB)]*100)/[Total_Space(MB)] AS DECIMAL(15,2)) AS '%_Free'
FROM
	(SELECT 
		DB_NAME() AS 'Database',
		df.name AS [File_Name], 
		ds.name AS [FileGroup_Name],
		df.physical_name AS [File_Path], 
		CAST((df.size/128.0) AS DECIMAL(15,2)) AS [Total_Space(MB)],
		CAST(df.size/128.0 - CAST(FILEPROPERTY(df.name, 'SpaceUsed') AS int)/128.0 AS DECIMAL(15,2)) AS [Available_Space(MB)]
	FROM	sys.database_files AS df WITH (NOLOCK) 
			LEFT OUTER JOIN sys.data_spaces AS ds WITH (NOLOCK) ON df.data_space_id = ds.data_space_id) AS Result;

 

Table wise Disk Space Usage:

The below query gets you the “Table Wise disk space information” which can be helpful to identify the critical tables in a given database , here you can find more information.

/**************************************************/
/**** Table wise Disk Space Report ****************/
/**** Tested: 2008, 2008 R2 ***********************/
/****	      2012, 2014, 2016 ********************/
/**************************************************/
SET NOCOUNT ON;
BEGIN TRY
	--Create a temparory table 
	CREATE TABLE #Tab (
			[Name]		 NVARCHAR(128),    
			[Rows]		 CHAR(11),    
			[Reserved]	 VARCHAR(18),  
			[Data]		 VARCHAR(18),     
			[Index_size] VARCHAR(18),    
			[Unused]	 VARCHAR(18)); 

	--Capture all tables data allocation information 
	INSERT #Tab 
	EXEC sp_msForEachTable 'EXEC sp_spaceused ''?''' ;

	--Alter Rows column datatype to BIGINT to get the result in sorted order
	ALTER TABLE #Tab ALTER COLUMN [ROWS] BIGINT  ;

	-- Get the final result: Remove KB and convert it into MB
	SELECT	Name,
		[Rows],
		CAST(LTRIM(RTRIM(REPLACE(Reserved,'KB',''))) AS BIGINT)/1024.0 AS 'Reserved MB',
		CAST(LTRIM(RTRIM(REPLACE(Data,'KB',''))) AS BIGINT)/1024.0 AS 'Data MB',
		CAST(LTRIM(RTRIM(REPLACE(Index_Size,'KB',''))) AS BIGINT)/1024.0 AS 'Index_Size MB',
		CAST(LTRIM(RTRIM(REPLACE(Unused,'KB',''))) AS BIGINT)/1024.0 AS 'Unused MB'
	FROM #Tab 
	ORDER BY [rows] DESC;

END TRY
BEGIN CATCH
	DROP TABLE #Tab; 
END CATCH
-- Drop the temparory table 
DROP TABLE #Tab; 

 

Using SSMS Standard Reports:

We can also check the disk space usage report from SSMS. Connect to the SQL Server instance from SSMS Right click on Database Reports Standard Reports Top 4 options are related to disk usage reports that you can see from the below image.

D:\Users\703124718.INDGE\Desktop\SQLServer_Space_Usage.jpg

XP_CMDSHELL:

XP_CMDSHELL gives us more control on hosted windows server and we can execute shell commands to get the drive and space information. In most of the environments we could see that this option is disabled as there is a security risk when this option enabled and no proper control on system administrator accounts. If in case this option is enabled in your environment you can try capturing the DISK Space information. Here is an example for automated disk space report using XP_CMDSHELL.

EXEC xp_cmdshell 'wmic logicaldisk get size,freespace,caption';

PowerShell Scripts:

This is one of the best options to automate the Disk Space monitoring procedure. It provides more flexibility and provides more options in capturing DISK Space details.

Link1

Link2

Link3

Note: SQL Server Space Usage report can be automated in various ways, to quickly check the current status we can choose using the system stored procedures, for the report automation PowerShell script is the best option.

sql-server-space-usage-scripts is the Script file with all scripts.

Posted in SQL Scripts, SQL Server DBA | Tagged , , , , , , , , , , , , | Leave a comment
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments