Reading SQL Server Wait Statistics Without Guessing
Wait statistics are one of the first things I check when a SQL Server instance "feels slow."
CPU and disk graphs can point in a direction, but sys.dm_os_wait_stats (or
sys.dm_exec_session_wait_stats for a single session) tells you what SQL Server itself has been
waiting on since the last restart or stats reset.
Start with a clean baseline
Wait stats accumulate from the moment the instance starts, so before drawing conclusions I clear them (in a non-production-impacting way, or by comparing deltas) and let the workload run for a representative window:
-- Clear wait stats to get a clean window (use with care, and understand your workload cycle first)
DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);
Group waits into categories, not raw wait types
Raw wait types are noisy - some are always present and not actionable (like SLEEP_TASK in idle
periods). I group waits into rough categories before drawing conclusions:
- CPU pressure:
SOS_SCHEDULER_YIELD, high signal wait time relative to resource wait time. - I/O pressure:
PAGEIOLATCH_*,WRITELOG. - Blocking:
LCK_M_*wait types. - Memory pressure:
RESOURCE_SEMAPHORE.
A basic architecture for ongoing monitoring
Why this matters
Wait statistics don't replace execution plan analysis or index review - they point you toward which of those to prioritize. Treating them as a triage step rather than a final answer has saved me from chasing the wrong fix more than once.
More posts on SQL Server performance, AWS architecture, and AI-assisted DBA automation are on the way.
