views:

652

answers:

5

My SQL Server CPU has been at around 90% for the most part of today.

I am not in a position to be able to restart it due to it being in constant use.

Is it possible to find out what within SQL is causing such a CPU overload?

I have run SQL Profiler but so much is going on it's difficult to tell if anything in particular is causing it.

I have run sp_who2 but am not sure what everything means exactly and if it is possible to identify possible problems in here.

To pre-empt any "it's probably just being used a lot" responses, this has only kicked in today from perfectly normal activitly levels.

I'm after any way of finding what is causing CPU grief within SQL.

A: 

Run either of these a few second apart. You'll detect the high CPU connection. Or: stored CPU in a local variable, WAITFOR DELAY, compare stored and current CPU values

select * from master..sysprocesses
where status = 'runnable' --comment this out
order by CPU
desc

select * from master..sysprocesses
order by CPU
desc

May not be the most elegant but it'd effective and quick.

gbn
Hi thanks for that, I did that and it came back with LOGMGR_QUEUE cpu column being at 20296. What unit is this figure in?
joshcomley
milliseconds. that's low
gbn
This is a Waittype too... ?
gbn
+2  A: 

For a GUI approach I would take a look at Activity Monitor under Management and sort by CPU.

cmsjr
Hopefully the GUI won't time out with the "lock timeout" error that happens on loaded SQL Server boxes...
gbn
For sure, but I suggested it because I have experienced the followingRandom Character: CPU critical!!!!!Me: Sounds like a job for system tables! <writing query furiously>Not Me: Don't worry about it, I found and killed the culprit in Activity Monitor.
cmsjr
So what was it then?
John Sansom
A stored procedure that generated data for a report. Lots of joins and aggregates, fragmented indexes. We re-wrote the query using with (nolock and rebuilt all the indexes and it stopped being a problem.
cmsjr
A: 

You can run the SQL Profiler, and filter by CPU or Duration so that you're excluding all the "small stuff". Then it should be a lot easier to determine if you have a problem like a specific stored proc that is running much longer than it should (could be a missing index or something).

Two caveats:

  • If the problem is massive amounts of tiny transactions, then the filter I describe above would exclude them, and you'd miss this.
  • Also, if the problem is a single, massive job (like an 8-hour analysis job or a poorly designed select that has to cross-join a billion rows) then you might not see this in the profiler until it is completely done, depending on what events you're profiling (sp:completed vs sp:statementcompleted).

But normally I start with the Activity Monitor or sp_who2.

BradC
+3  A: 

This query uses DMV's to identify the most costly quereis by CPU

SELECT TOP 20
    qs.sql_handle,
    qs.execution_count,
    qs.total_worker_time AS Total_CPU,
    total_CPU_inSeconds = --Converted from microseconds
        qs.total_worker_time/1000000,
    average_CPU_inSeconds = --Converted from microseconds
     (qs.total_worker_time/1000000) / qs.execution_count,
    qs.total_elapsed_time,
    total_elapsed_time_inSeconds = --Converted from microseconds
     qs.total_elapsed_time/1000000,
   st.text,
   qp.query_plan
from
    sys.dm_exec_query_stats as qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as st
    cross apply sys.dm_exec_query_plan (qs.plan_handle) as qp
ORDER BY qs.total_worker_time desc

For a complete explanation see: How to identify the most costly SQL Server queries by CPU

John Sansom
What if it's system related: VLFs, checkpointing, stats rebuilds etc
gbn
+2  A: 

I assume due diligence here that you confirmed the CPU is actually consumed by SQL process (perfmon Process category counters would confirm this). Normally for such cases you take a sample of the relevant performance counters and you compare them with a baseline that you established in normal load operating conditions. Once you resolve this problem I recommend you do establish such a baseline for future comparisons.

You can find exactly where is SQL spending every single CPU cycle. But knowing where to look takes a lot of know how and experience. Is is SQL 2005/2008 or 2000 ? Fortunately for 2005 and newer there are a couple of off the shelf solutions. You already got a couple good pointer here with John Samson's answer. I'd like to add a recommendation to download and install the SQL Server Performance Dashboard Reports. Some of those reports include top queries by time or by I/O, most used data files and so on and you can quickly get a feel where the problem is. The output is both numerical and graphical so it is more usefull for a beginner.

I would also recommend using Adam's Who is Active script, although that is a bit more advanced.

And last but not least I recommend you download and read the MS SQL Customer Advisory Team white paper on performance analysis: SQL 2005 Waits and Queues.

My recommendation is also to look at I/O. If you added a load to the server that trashes the buffer pool (ie. it needs so much data that it evicts the cached data pages from memory) the result would be a significant increase in CPU (sounds surprising, but is true). The culprit is usually a new query that scans a big table end-to-end.

Remus Rusanu