SQL Server High CPU: What to Check First, in Order

Find out whether SQL Server is working or waiting before you touch a setting. Take the waits over a short interval, look at what is running right now, and only then go after the query. High CPU is usually one or two queries doing far too much work; it is almost never fixed by lowering MAXDOP, and the two most common causes, a plan that stopped fitting its parameter and a statistic that went stale, leave no trace in any configuration setting.

What the Symptom Is Telling You

“SQL Server is at 100 percent CPU” describes one of four different problems, and the first two minutes decide which. The checks below are in the order that separates them fastest, and each one hands off to the script or the explainer that does the work, so this page is a route, not a fifth explanation of parallelism.

What you seeWhat it usually isStart at
CPU pegged, users report slowness, one or two sessions dominateRunaway queries: a bad plan, a missing index, a scan that should be a seekSteps 2 and 3
CPU high, many sessions runnable, waits dominated by SOS_SCHEDULER_YIELDGenuine CPU pressure: more work than cores, or too much parallelismSteps 1 and 5
CPU high, connections hang or time out, THREADPOOL waitsWorker thread exhaustion, usually blocking underneathStep 4
CPU high with almost nothing runningSomething outside SQL Server on the box, or the OS trimming SQL Server’s memoryStep 5

STEP1

Step 1: Is It Working or Waiting?

Run Get Wait Statistics twice a minute apart and read the difference, not the totals; cumulative wait stats lie because the top of the cumulative list is whatever the instance has been doing since it last started. If SOS_SCHEDULER_YIELD leads the interval, threads are giving up the CPU because other threads want it: the box is genuinely busy, and the question becomes which queries. If CXPACKET leads, parallel queries are coordinating, which is normal on its own and a problem only when the same few queries are going parallel that should not. If lock waits lead, this is not a CPU problem at all; go to the blocking walkthrough instead.


STEP2

Step 2: What Is Running Right Now?

Get Long-Running Queries shows every executing request with its CPU time against its elapsed time. A request whose CPU time is close to its elapsed time is working; one with high elapsed time and low CPU is waiting, and the wait type column says on what. Two or three sessions with large CPU time and status = running or runnable are usually the whole story, and statement_text tells you which statement inside the batch.


STEP3

Step 3: Which Query, and Why Is It Expensive?

Get Top CPU Queries ranks the plan cache by total and average CPU, so a query that runs ten thousand times cheaply and one that runs once expensively both show up in the right place. If Query Store is on, Get Query Store Top Queries gives the same view with history, which is how you see that the plan changed on Tuesday. With the query in hand, the three usual reasons it is expensive, in the order they turn out to be true:

The plan stopped fitting its parameter. Parameter sniffing is SQL Server compiling once for the first value it saw and reusing that plan for every value after, and the post measures it rather than describing it. The statistics are stale. Get Statistics Health finds the tables whose data moved and whose statistics did not, which is the same symptom from the other side. The query is scanning when it could seek. Get Missing Indexes lists what the optimiser wanted and did not have, and Get Implicit Conversions finds the quiet data type mismatch that turns a seek into a scan without anyone changing the query.


STEP4

Step 4: Are Connections Hanging as Well?

If the symptom is not only high CPU but new connections timing out, run Get Worker Threads and Active Sessions. A worker pool near its limit with THREADPOOL waits means requests cannot get a thread at all, and the usual cause underneath is blocking, every waiting session holding a thread while it waits. Get Blocking Summary finds the head of the chain; killing anything else does nothing.


STEP5

Step 5: Only Now, the Settings

Get CPU Topology and OS Configuration reads what SQL Server can see: logical CPUs, schedulers online, NUMA layout, and the OS settings that decide whether Windows can take memory back from it. MAXDOP and cost threshold are the two settings people reach for first and should reach for last: MAXDOP 0 lets one query take every core, cost threshold 5 sends trivial queries parallel, and both defaults are wrong on a modern server, but changing them treats the symptom of Step 3, not the cause. Change them from the published table, once, after the queries are fixed, and watch a full business cycle.


Frequently Asked Questions

Should I lower MAXDOP to fix high CPU?
Almost never as the first move. Lowering MAXDOP makes every parallel query slower to reduce the CPU one of them is burning, which is the wrong trade. Find the query first (Steps 2 and 3); MAXDOP and cost threshold get set from the published guidance afterwards, and usually the fix is raising cost threshold, not lowering MAXDOP.
Task Manager says sqlservr.exe is at 100 percent. Is that the same thing?
It is the same symptom seen from outside. SQL Server will use every core it is allowed to when there is work, so the number on its own is not a fault; what matters is whether the work is legitimate. Step 1 answers that in one interval: a busy server with sensible waits is fine, a busy server running one runaway query is not.
CPU is high but nothing is running. What now?
Check what else is on the box: backup agents, antivirus scanning data files, a second instance, SSRS or SSIS on the same server. Then check the OS side with the topology script, because Windows trimming SQL Server’s working set shows up as I/O and CPU that no query explains.
How do I know whether it was always like this?
Query Store, if it was on, has the history per query and shows the plan change. Without it, the wait stats since the last restart give a rough shape, and the cumulative counters reset when the service restarts, so check the start time before trusting them.

Related

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *