Skip to content

Commit 5aa4d5c

Browse files
CopilotBrentOzar
andauthored
Add sp_BlitzFirst high thread-time warning check
Agent-Logs-Url: https://github.com/BrentOzarULTD/SQL-Server-First-Responder-Kit/sessions/ea4a3608-fc29-40b8-91dd-f2ee831873b1 Co-authored-by: BrentOzar <245462+BrentOzar@users.noreply.github.com>
1 parent eb8a91d commit 5aa4d5c

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

Documentation/sp_BlitzFirst_Checks_by_Priority.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Before adding a new check, make sure to add a Github issue for it first, and hav
66

77
If you want to change anything about a check - the priority, finding, URL, or ID - open a Github issue first. The relevant scripts have to be updated too.
88

9-
CURRENT HIGH CHECKID: 53
10-
If you want to add a new check, start at 54.
9+
CURRENT HIGH CHECKID: 54
10+
If you want to add a new check, start at 55.
1111

1212
| Priority | FindingsGroup | Finding | URL | CheckID |
1313
|----------|---------------------------------|---------------------------------------|-------------------------------------------------|----------|
@@ -17,6 +17,7 @@ If you want to add a new check, start at 54.
1717
| 1 | Maintenance Tasks Running | Backup Running | https://www.brentozar.com/askbrent/backups | 1 |
1818
| 1 | Maintenance Tasks Running | DBCC CHECK* Running | https://www.brentozar.com/askbrent/dbcc | 2 |
1919
| 1 | Maintenance Tasks Running | Restore Running | https://www.brentozar.com/askbrent/backups | 3 |
20+
| 1 | Potential Upcoming Problems | High Thread Time | https://www.brentozar.com/go/threadtime | 54 |
2021
| 1 | Query Problems | Long-Running Query Blocking Others | https://www.brentozar.com/go/blocking | 5 |
2122
| 1 | Query Problems | Query Rolling Back | https://www.brentozar.com/go/rollback | 9 |
2223
| 1 | Query Problems | Sleeping Query with Open Transactions | https://www.brentozar.com/go/sleeping | 8 |

sp_BlitzFirst.sql

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3475,6 +3475,70 @@ If one of them is a lead blocker, consider killing that query.'' AS HowToStopit,
34753475
SELECT CAST((wd2.thread_time_ms - wd1.thread_time_ms) / 1000 AS INT) AS TotalThreadTimeSeconds
34763476
) AS c;
34773477

3478+
/* Potential Upcoming Problems - High Thread Time - CheckID 54 */
3479+
IF @Seconds > 0
3480+
BEGIN
3481+
IF (@Debug = 1)
3482+
BEGIN
3483+
RAISERROR('Running CheckID 54',10,1) WITH NOWAIT;
3484+
END
3485+
3486+
;WITH max_batch AS (
3487+
SELECT MAX(SampleTime) AS SampleTime
3488+
FROM #WaitStats
3489+
),
3490+
thread_time AS (
3491+
SELECT TOP 1
3492+
wd1.SampleTime AS StartSampleTime,
3493+
wd2.SampleTime AS EndSampleTime,
3494+
CAST((wd2.thread_time_ms - wd1.thread_time_ms) / 1000.0 AS DECIMAL(18,1)) AS TotalThreadTimeSeconds
3495+
FROM max_batch b
3496+
JOIN #WaitStats wd2 ON wd2.SampleTime = b.SampleTime
3497+
JOIN #WaitStats wd1 ON wd1.wait_type = wd2.wait_type AND wd2.SampleTime > wd1.SampleTime
3498+
ORDER BY wd2.SampleTime DESC, wd1.SampleTime ASC
3499+
),
3500+
non_idle_waits AS (
3501+
SELECT CAST(SUM((wNow.wait_time_ms - COALESCE(wBase.wait_time_ms, 0)) / 1000.0) AS DECIMAL(18,1)) AS NonIdleWaitSeconds
3502+
FROM #WaitStats wNow
3503+
LEFT OUTER JOIN #WaitStats wBase ON wNow.wait_type = wBase.wait_type AND wNow.SampleTime > wBase.SampleTime
3504+
LEFT OUTER JOIN ##WaitCategories wc ON wc.WaitType = wNow.wait_type
3505+
WHERE wNow.Pass = 2
3506+
AND (wc.WaitCategory IS NULL OR wc.WaitCategory <> 'Idle')
3507+
),
3508+
cores AS (
3509+
SELECT SUM(1) AS cpu_count
3510+
FROM sys.dm_os_schedulers
3511+
WHERE status = 'VISIBLE ONLINE'
3512+
AND is_online = 1
3513+
)
3514+
INSERT INTO #BlitzFirstResults (CheckID, Priority, FindingsGroup, Finding, URL, Details, DetailsInt)
3515+
SELECT
3516+
54 AS CheckID,
3517+
1 AS Priority,
3518+
'Potential Upcoming Problems' AS FindingsGroup,
3519+
'High Thread Time' AS Finding,
3520+
'https://www.brentozar.com/go/threadtime' AS URL,
3521+
CAST(CAST(c.CpuTimeUsedSeconds AS DECIMAL(18,1)) AS NVARCHAR(30))
3522+
+ ' CPU time used out of a theoretical max of '
3523+
+ CAST(CAST(t.TheoreticalMaxCpuSeconds AS DECIMAL(18,1)) AS NVARCHAR(30))
3524+
+ ' seconds. As CPU time used starts to approach 80-90%, the server can quickly become unresponsive. Be prepared to troubleshoot with the DAC.' AS Details,
3525+
CAST(c.CpuTimeUsedSeconds AS INT) AS DetailsInt
3526+
FROM thread_time tt
3527+
CROSS JOIN non_idle_waits niw
3528+
CROSS JOIN cores i
3529+
CROSS APPLY (
3530+
SELECT CAST(i.cpu_count * DATEDIFF(ss, tt.StartSampleTime, tt.EndSampleTime) AS DECIMAL(18,1)) AS TheoreticalMaxCpuSeconds
3531+
) t
3532+
CROSS APPLY (
3533+
SELECT CAST(CASE
3534+
WHEN tt.TotalThreadTimeSeconds - COALESCE(niw.NonIdleWaitSeconds, 0) < 0 THEN 0
3535+
ELSE tt.TotalThreadTimeSeconds - COALESCE(niw.NonIdleWaitSeconds, 0)
3536+
END AS DECIMAL(18,1)) AS CpuTimeUsedSeconds
3537+
) c
3538+
WHERE t.TheoreticalMaxCpuSeconds > 0
3539+
AND c.CpuTimeUsedSeconds >= (t.TheoreticalMaxCpuSeconds * 0.5);
3540+
END;
3541+
34783542
/* Server Info - Batch Requests per Sec - CheckID 19 */
34793543
IF (@Debug = 1)
34803544
BEGIN

0 commit comments

Comments
 (0)