Tech Blog – Scripts – MSSQL Diagnostic Cheat Sheet
Get Best Practise Info
-- Get best practise info
SELECT
[name] AS 'SQL Configuration',
[value_in_use] AS 'Values'
FROM
sys.configurations
WHERE
[name] = 'optimize for ad hoc workloads'
or
[name] = 'cost threshold for parallelism'
or
[name] = 'max degree of parallelism'
or
[name] = 'max server memory (MB)'
or
[name] = 'scan for startup procs'
UNION
SELECT
'read committed snapshot is enabled on ' [name],
[name] [is_read_committed_snapshot_on]
FROM sys.databases
WHERE [name] NOT IN ('master', 'msdb','model','distribution','tempdb')
AND [is_read_committed_snapshot_on] >0
Get Disk & Space Info
SELECT DISTINCT
vs.volume_mount_point,
vs.file_system_type,
vs.logical_volume_name,
CONVERT(DECIMAL(18,2),vs.total_bytes/1073741824.0) AS [Total Size (GB)],
CONVERT(DECIMAL(18,2), vs.available_bytes/1073741824.0) AS [Available Size (GB)],
CONVERT(DECIMAL(18,2), vs.available_bytes * 1. / vs.total_bytes * 100.) AS [Space Free %]
FROM sys.master_files AS f WITH (NOLOCK)
CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.[file_id]) AS vs
ORDER BY vs.volume_mount_point OPTION (RECOMPILE);
Get Hardware Info
Get Instance Level Configs
-- Get instance-level config
SELECT name, value, value_in_use, minimum, maximum, [description], is_dynamic, is_advanced
FROM sys.configurations WITH (NOLOCK)
ORDER BY name OPTION (RECOMPILE);
Get Database Level Configs (recovery, log & common options)
Get Last Backup Times
Get Sizes Of All Databases
-- Get sizes of all databases and store into a temp table.
DECLARE @command NVARCHAR(MAX)
DROP TABLE IF EXISTS #MSSQL_Database_Sizes
CREATE TABLE #MSSQL_Database_Sizes ([DatabaseName] [nvarchar](max) NULL, [CurrentSizeMB] [int] NULL, [FreeSpaceMB] [int] NULL, [CollectionDate] [date] NULL)
SELECT @command =
'USE ?
INSERT INTO #MSSQL_Database_Sizes ([DatabaseName], CurrentSizeMB, FreeSpaceMB, [CollectionDate])
SELECT
[name] AS [Database],
[size]/128.0 AS [CurrentSizeMB],
[size]/128.0 - CAST(FILEPROPERTY([name], ' + '''SpaceUsed''' + ') AS INT)/128.0 AS [FreeSpaceMB],
CAST(GETDATE() AS DATE) AS [CollectionDate]
FROM sys.database_files
WHERE [type] = 0'
EXEC sp_MSforeachdb @command
SELECT *
FROM #MSSQL_Database_Sizes
ORDER BY 3 DESC
Get Table Sizes (database scoped)
SELECT
t.NAME AS TableName,
s.Name AS SchemaName,
p.rows AS RowCounts,
CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB,
CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN
sys.schemas s ON t.schema_id = s.schema_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
GROUP BY
t.Name, s.Name, p.Rows
ORDER BY
t.Name
Get CPU Utilisation By Database
Get IO Utilisation By Database
Get Top Avg. Elapsed Query Time On Instance
Get Most Frequently Executed Queries On Database
Get SQL Agent & Category Info
Get Database File Path & Growth Info
Get Fragmentation & Forward Record Counts
-- Get Fragmentation &Amp; Stats On A SQL Database
-- This May Take Time To Return Results On A Heavy Server.
-- Run Against Largest Database First Before Using Sp_MSforeachdb (2nd Script Below).
-- ##### Run Against An Individual Database #####
SELECT
Sysdbs.[Name],
Index_id,
Object_name([Object_id]) AS TableName,
CASE WHEN Sysindx.Name Is Null THEN 'HEAP' ELSE Sysindx.Name END AS IndexName,
Index_type_desc,
Avg_fragmentation_in_percent,
Forwarded_record_count
FROM
Sys.Dm_db_index_physical_stats(Db_id(),Object_id('HeapRebuildTest'),Null,Null,'Detailed') AS Sysindxphyst
INNER JOIN Sys.Sysindexes AS Sysindx ON Sysindxphyst.[Object_id] = Sysindx.[Id] AND Sysindxphyst.Index_id = Sysindx.Indid
INNER JOIN Sys.Databases AS Sysdbs ON Sysindxphyst.[Database_id] = Sysdbs.[Database_id]
WHERE
Index_level = 0
ORDER BY
[Avg_fragmentation_in_percent] DESC
-- ##### Run Against All Databases - Change of database/table name required #####
DROP TABLE IF EXISTS [insight_team].[dbo].[MSSQL_Fragmentation]
CREATE TABLE [insight_team].[dbo].[MSSQL_Fragmentation](
[Name] [sysname] NOT NULL,
[Index_id] [int] NULL,
[TableName] [nvarchar](128) NULL,
[IndexName] [nvarchar](128) NULL,
[Index_type_desc] [nvarchar](60) NULL,
[Avg_fragmentation_in_percent] [float] NULL,
[Forwarded_record_count] [bigint] NULL
) ON [PRIMARY]
EXEC Sp_MSforeachdb 'USE ?
INSERT INTO [insight_team].[dbo].[fragmentation_10feb] (Name,Index_id,TableName,IndexName,Index_type_desc,Avg_fragmentation_in_percent,Forwarded_record_count)
SELECT
Sysdbs.[Name],
Index_id,
Object_name([Object_id]) AS TableName,
CASE WHEN Sysindx.Name Is Null THEN ''HEAP'' ELSE Sysindx.Name END AS IndexName,
Index_type_desc,
Avg_fragmentation_in_percent,
Forwarded_record_count
FROM
Sys.Dm_db_index_physical_stats(Db_id(),Object_id(''HeapRebuildTest''),Null,Null,''Detailed'') AS Sysindxphyst
INNER JOIN Sys.Sysindexes AS Sysindx ON Sysindxphyst.[Object_id] = Sysindx.[Id] AND Sysindxphyst.Index_id = Sysindx.Indid
INNER JOIN Sys.Databases AS Sysdbs ON Sysindxphyst.[Database_id] = Sysdbs.[Database_id]
WHERE
Index_level = 0
ORDER BY
[Avg_fragmentation_in_percent] DESC'
-- Show Most Fragmented Indexes.
SELECT *
FROM [insight_team].[dbo].[fragmentation_10feb]
WHERE Index_type_desc <> 'HEAP'
ORDER BY [Avg_fragmentation_in_percent] DESC
-- Show Highest Counts Of Forward Records.
SELECT *
FROM [insight_team].[dbo].[fragmentation_10feb]
ORDER BY [Forwarded_record_count] DESC
-- Show Total Forward Record Counts On SQL Instance.
SELECT SUM(Forwarded_record_count) AS 'Total_forward_records'
FROM [insight_team].[dbo].[fragmentation_10feb]
-- Show Which Databases Have The Most Forward Records
SELECT [Name], SUM(Forwarded_record_count) AS 'Total_forward_records'
FROM [insight_team].[dbo].[fragmentation_10feb]
GROUP BY [Name]
ORDER BY [Total_forward_records] DESC
Get Database Growth Events
Get VLF Counts For All Databases
-- Get VLF Counts for all databases
SELECT [name] AS [Database Name], [VLF Count]
FROM sys.databases AS db WITH (NOLOCK)
CROSS APPLY (SELECT file_id, COUNT(*) AS [VLF Count]
FROM sys.dm_db_log_info(db.database_id)
GROUP BY file_id) AS li
ORDER BY [VLF Count] DESC OPTION (RECOMPILE);
Get SQL Services Info
-- SQL Server Services Info
SELECT servicename, process_id, startup_type_desc, status_desc,
last_startup_time, service_account, is_clustered, cluster_nodename, [filename],
instant_file_initialization_enabled -- New in SQL Server 2016 SP1
FROM sys.dm_server_services WITH (NOLOCK) OPTION (RECOMPILE);