1
1
2
2
-- SQL Server 2016 Diagnostic Information Queries
3
3
-- Glenn Berry
4
- -- Last Modified: November 1, 2024
4
+ -- Last Modified: March 1, 2025
5
5
-- https://glennsqlperformance.com/
6
6
-- https://sqlserverperformance.wordpress.com/
7
7
-- YouTube: https://bit.ly/2PkoAM1
8
- -- Twitter: GlennAlanBerry
8
+ -- Blue Sky: https://bsky.app/profile/glennalanberry.bsky.social
9
9
10
10
-- Diagnostic Queries are available here
11
11
-- https://glennsqlperformance.com/resources/
25
25
26
26
27
27
-- ******************************************************************************
28
- -- * Copyright (C) 2024 Glenn Berry
28
+ -- * Copyright (C) 2025 Glenn Berry
29
29
-- * All rights reserved.
30
30
-- *
31
31
-- *
@@ -56,6 +56,9 @@ IF NOT EXISTS (SELECT * WHERE CONVERT(varchar(128), SERVERPROPERTY('ProductVersi
56
56
SELECT @@SERVERNAME AS [Server Name], @@VERSION AS [SQL Server and OS Version Info];
57
57
-- ----
58
58
59
+ -- SQL Server 2016 is out of mainstream from Microsoft
60
+
61
+
59
62
-- SQL Server 2016 RTM Branch Builds -- SQL Server 2016 SP1 Branch Builds -- SQL Server 2016 SP2 Branch Builds
60
63
-- Build Description Release Date Build Description Release Date Build Description Release Date
61
64
-- 13.0.200.172 CTP 2.0 5/26/2015
@@ -123,9 +126,6 @@ SELECT @@SERVERNAME AS [Server Name], @@VERSION AS [SQL Server and OS Version In
123
126
-- Download SQL Server Management Studio (SSMS)
124
127
-- https://bit.ly/1OcupT9
125
128
126
- -- Download and install Azure Data Studio
127
- -- https://bit.ly/2vgke1A
128
-
129
129
-- SQL Server 2016 Configuration Manager is SQLServerManager13.msc
130
130
131
131
-- SQL Server troubleshooting (Microsoft documentation resources)
@@ -1498,21 +1498,21 @@ ORDER BY qs.execution_count DESC OPTION (RECOMPILE);
1498
1498
-- Queries 55 through 61 are the "Bad Man List" for stored procedures
1499
1499
1500
1500
-- Top Cached SPs By Execution Count (Query 55) (SP Execution Counts)
1501
- SELECT TOP (50 ) LEFT (t.[text], 50 ) AS [Short Query Text], qs .execution_count AS [Execution Count],
1502
- qs .total_logical_reads AS [Total Logical Reads],
1503
- qs .total_logical_reads / qs .execution_count AS [Avg Logical Reads],
1504
- qs .total_worker_time AS [Total Worker Time],
1505
- qs .total_worker_time / qs .execution_count AS [Avg Worker Time],
1506
- qs .total_elapsed_time AS [Total Elapsed Time],
1501
+ SELECT TOP (100 ) CONCAT (SCHEMA_NAME (p .schema_id ), ' .' , p .name ) AS [SP Name], qs .execution_count AS [Execution Count],
1502
+ ISNULL (qs .execution_count / DATEDIFF (Minute, qs .cached_time , GETDATE ()), 0 ) AS [Calls/Minute],
1507
1503
qs .total_elapsed_time / qs .execution_count AS [Avg Elapsed Time],
1504
+ qs .total_worker_time / qs .execution_count AS [Avg Worker Time],
1505
+ qs .total_logical_reads / qs .execution_count AS [Avg Logical Reads],
1508
1506
CASE WHEN CONVERT (nvarchar (max ), qp .query_plan ) COLLATE Latin1_General_BIN2 LIKE N ' %<MissingIndexes>%' THEN 1 ELSE 0 END AS [Has Missing Index],
1509
1507
CONVERT (nvarchar (25 ), qs .last_execution_time , 20 ) AS [Last Execution Time],
1510
- CONVERT (nvarchar (25 ), qs .creation_time , 20 ) AS [Plan Cached Time]
1511
- -- ,t.[text] AS [Complete Query Text], qp.query_plan AS [Query Plan] -- uncomment out these columns if not copying results to Excel
1512
- FROM sys .dm_exec_query_stats AS qs WITH (NOLOCK )
1513
- CROSS APPLY sys .dm_exec_sql_text (plan_handle) AS t
1514
- CROSS APPLY sys .dm_exec_query_plan (plan_handle) AS qp
1515
- WHERE t .dbid = DB_ID ()
1508
+ CONVERT (nvarchar (25 ), qs .cached_time , 20 ) AS [Plan Cached Time]
1509
+ -- ,qp.query_plan AS [Query Plan] -- Uncomment if you want the Query Plan
1510
+ FROM sys .procedures AS p WITH (NOLOCK )
1511
+ INNER JOIN sys .dm_exec_procedure_stats AS qs WITH (NOLOCK )
1512
+ ON p.[object_id] = qs.[object_id]
1513
+ CROSS APPLY sys .dm_exec_query_plan (qs .plan_handle ) AS qp
1514
+ WHERE qs .database_id = DB_ID ()
1515
+ AND DATEDIFF (Minute, qs .cached_time , GETDATE ()) > 0
1516
1516
ORDER BY qs .execution_count DESC OPTION (RECOMPILE );
1517
1517
-- ----
1518
1518
@@ -1522,7 +1522,7 @@ ORDER BY qs.execution_count DESC OPTION (RECOMPILE);
1522
1522
1523
1523
1524
1524
-- Top Cached SPs By Avg Elapsed Time (Query 56) (SP Avg Elapsed Time)
1525
- SELECT TOP (25 ) p . name AS [SP Name], qs .min_elapsed_time , qs .total_elapsed_time / qs .execution_count AS [avg_elapsed_time],
1525
+ SELECT TOP (25 ) CONCAT ( SCHEMA_NAME ( p . schema_id ), ' .' , p . name ) AS [SP Name], qs .min_elapsed_time , qs .total_elapsed_time / qs .execution_count AS [avg_elapsed_time],
1526
1526
qs .max_elapsed_time , qs .last_elapsed_time , qs .total_elapsed_time , qs .execution_count ,
1527
1527
ISNULL (qs .execution_count / DATEDIFF (Minute, qs .cached_time , GETDATE ()), 0 ) AS [Calls/Minute],
1528
1528
qs .total_worker_time / qs .execution_count AS [AvgWorkerTime],
@@ -1546,7 +1546,7 @@ ORDER BY avg_elapsed_time DESC OPTION (RECOMPILE);
1546
1546
1547
1547
1548
1548
-- Top Cached SPs By Total Worker time. Worker time relates to CPU cost (Query 57) (SP Worker Time)
1549
- SELECT TOP (25 ) p . name AS [SP Name], qs .total_worker_time AS [TotalWorkerTime],
1549
+ SELECT TOP (25 ) CONCAT ( SCHEMA_NAME ( p . schema_id ), ' .' , p . name ) AS [SP Name], qs .total_worker_time AS [TotalWorkerTime],
1550
1550
qs .total_worker_time / qs .execution_count AS [AvgWorkerTime], qs .execution_count ,
1551
1551
ISNULL (qs .execution_count / DATEDIFF (Minute, qs .cached_time , GETDATE ()), 0 ) AS [Calls/Minute],
1552
1552
qs .total_elapsed_time , qs .total_elapsed_time / qs .execution_count AS [avg_elapsed_time],
@@ -1568,7 +1568,7 @@ ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);
1568
1568
1569
1569
1570
1570
-- Top Cached SPs By Total Logical Reads. Logical reads relate to memory pressure (Query 58) (SP Logical Reads)
1571
- SELECT TOP (25 ) p . name AS [SP Name], qs .total_logical_reads AS [TotalLogicalReads],
1571
+ SELECT TOP (25 ) CONCAT ( SCHEMA_NAME ( p . schema_id ), ' .' , p . name ) AS [SP Name], qs .total_logical_reads AS [TotalLogicalReads],
1572
1572
qs .total_logical_reads / qs .execution_count AS [AvgLogicalReads],qs .execution_count ,
1573
1573
ISNULL (qs .execution_count / DATEDIFF (Minute, qs .cached_time , GETDATE ()), 0 ) AS [Calls/Minute],
1574
1574
qs .total_elapsed_time , qs .total_elapsed_time / qs .execution_count AS [avg_elapsed_time],
@@ -1590,7 +1590,7 @@ ORDER BY qs.total_logical_reads DESC OPTION (RECOMPILE);
1590
1590
1591
1591
1592
1592
-- Top Cached SPs By Total Physical Reads. Physical reads relate to disk read I/O pressure (Query 59) (SP Physical Reads)
1593
- SELECT TOP (25 ) p . name AS [SP Name],qs .total_physical_reads AS [TotalPhysicalReads],
1593
+ SELECT TOP (25 ) CONCAT ( SCHEMA_NAME ( p . schema_id ), ' .' , p . name ) AS [SP Name], qs .total_physical_reads AS [TotalPhysicalReads],
1594
1594
qs .total_physical_reads / qs .execution_count AS [AvgPhysicalReads], qs .execution_count ,
1595
1595
qs .total_logical_reads ,qs .total_elapsed_time , qs .total_elapsed_time / qs .execution_count AS [avg_elapsed_time],
1596
1596
CASE WHEN CONVERT (nvarchar (max ), qp .query_plan ) COLLATE Latin1_General_BIN2 LIKE N ' %<MissingIndexes>%' THEN 1 ELSE 0 END AS [Has Missing Index],
@@ -1613,7 +1613,7 @@ ORDER BY qs.total_physical_reads DESC, qs.total_logical_reads DESC OPTION (RECOM
1613
1613
1614
1614
-- Top Cached SPs By Total Logical Writes (Query 60) (SP Logical Writes)
1615
1615
-- Logical writes relate to both memory and disk I/O pressure
1616
- SELECT TOP (25 ) p . name AS [SP Name], qs .total_logical_writes AS [TotalLogicalWrites],
1616
+ SELECT TOP (25 ) CONCAT ( SCHEMA_NAME ( p . schema_id ), ' .' , p . name ) AS [SP Name], qs .total_logical_writes AS [TotalLogicalWrites],
1617
1617
qs .total_logical_writes / qs .execution_count AS [AvgLogicalWrites], qs .execution_count ,
1618
1618
ISNULL (qs .execution_count / DATEDIFF (Minute, qs .cached_time , GETDATE ()), 0 ) AS [Calls/Minute],
1619
1619
qs .total_elapsed_time , qs .total_elapsed_time / qs .execution_count AS [avg_elapsed_time],
@@ -1637,7 +1637,7 @@ ORDER BY qs.total_logical_writes DESC OPTION (RECOMPILE);
1637
1637
1638
1638
1639
1639
-- Cached SPs Missing Indexes by Execution Count (Query 61) (SP Missing Index)
1640
- SELECT TOP (25 ) p . name AS [SP Name], qs .execution_count AS [Execution Count],
1640
+ SELECT TOP (25 ) CONCAT ( SCHEMA_NAME ( p . schema_id ), ' .' , p . name ) AS [SP Name], qs .execution_count AS [Execution Count],
1641
1641
ISNULL (qs .execution_count / DATEDIFF (Minute, qs .cached_time , GETDATE ()), 0 ) AS [Calls/Minute],
1642
1642
qs .total_elapsed_time / qs .execution_count AS [Avg Elapsed Time],
1643
1643
qs .total_worker_time / qs .execution_count AS [Avg Worker Time],
@@ -1732,7 +1732,8 @@ ORDER BY index_advantage DESC OPTION (RECOMPILE);
1732
1732
-- Find missing index warnings for cached plans in the current database (Query 65) (Missing Index Warnings)
1733
1733
-- Note: This query could take some time on a busy instance
1734
1734
SELECT TOP (25 ) OBJECT_NAME (objectid) AS [ObjectName],
1735
- cp .objtype , cp .usecounts , cp .size_in_bytes , qp .query_plan
1735
+ cp .objtype , cp .usecounts , cp .size_in_bytes
1736
+ , qp .query_plan -- Uncomment if you want the Query Plan
1736
1737
FROM sys .dm_exec_cached_plans AS cp WITH (NOLOCK )
1737
1738
CROSS APPLY sys .dm_exec_query_plan (cp .plan_handle ) AS qp
1738
1739
WHERE CAST (qp .query_plan AS NVARCHAR (MAX )) LIKE N ' %MissingIndex%'
0 commit comments