How to Find Out Whose Queries are Using The Most CPU

You’ve got a bunch of users on the same SQL Server, and you wanna know who’s using the most resources. SQL Server doesn’t make this easy. You can query some management views to see which queries or databases have been using the most resources, but you can’t intuitively tell which USERS are.

To solve this problem, we’re going to use Resource Governor.

Wait. Come back.

When Resource Governor first came out, it didn’t get a lot of adoption. It’s an Enterprise Edition only feature, and its main job is to make queries slower. That’s rather unfortunate, since I don’t have a lot of folks coming to me saying, “Hey Brent, can you make my queries slower?” They don’t need to hire me for that – they have their own business intelligence department to take care of that.

We’re going to use just part of Resource Governor’s functionality:

  1. Create workload pools as if we were going to cap/limit people’s CPU power
  2. Create a classifier function so that when they log in, we can put them into different pools
  3. Set limits on each workload pool’s CPU
  4. Use Resource Governor’s reporting DMVs to query who’s been burning up our processors

You can watch me write this blog post, or keep reading for the script and demo version:

Configure Resource Governor to put people into groups.

What you’re about to read is by no means any kind of good practice. Here, I’m just showing you how to quickly configure Resource Governor as a proof of concept. Any database person worth their weight in Query Bucks would read the Resource Governor documentation before actually implementing this in real life. You, dear reader, are not actually worth your weight in Query Bucks, so you’re probably going to just copy/paste this into production. That’s why I like you.

Eagle-eyed readers like yourself will notice that I commented out the RECONFIGURE at the end. Resource Governor can be pretty dangerous: you can get yourself into a situation where people have trouble running queries because of goofs in the classifier function. Only run that final RECONFIGURE in a dev environment first and make sure you’re getting the results you’re aiming for.

Measure which groups of users are using the most CPU.

To do that, check out the DMV sys.dm_resource_governor_resource_pools:

The result shows you how much CPU each group has consumed:

When you start examining this data, you might find that your first pass of creating pools & groups ends up with not-very-granular reporting data. Maybe 80% of the server’s CPU is burned up by a single group – that’s not very actionable. From there, you want to continue creating smaller and smaller groups until you can figure out exactly who or what application is burning up the most CPU power.

This DMV’s contents reset when the SQL Server service restarts. You’re going to be tempted to hoard this data by logging it every day into a table, and I think that’s a bad idea. Just like you made a lot of bad decisions in your youth when you were young and you needed the money, so did the rest of the people on your team. Every time the SQL Server instance starts up, think of it as a brand new day. The folks writing terrible queries may have learned the errors of their ways and turned over a fresh new leaf, read themselves a good Itzik Ben Gan book on T-SQL, and only written magically well-tuned queries since then.

Ah, probably not.

Previous Post
European Union Folks: Wanna Attend Mastering Index Tuning?
Next Post
How Do I Know If My Query Is Good Enough for Production?

6 Comments. Leave new

  • Once you’ve configured resource pools/workload groups you’ll be able to access a lot of great data via performance counters.

    If you have infrastructure to collect perf counters this is a very low-friction way of understanding how different applications impact SQL Server – and not just from a CPU perspective (we’ve found counters like active requests, memory grants, and requests completed very useful).

    The documentation around some counters is a little lacking, and some of them we were never able to make sense of (the IO counters in particular were sketchy, and a MSFT support ticket didn’t shed much light there).

    Ignoring the governance side, we’ve had great success with monitoring via resource pools.

    Reply
  • This seems, only moderately useful to me. Like I might be able to say, hey payroll team, you’re using too much CPU. But when they ask which query(s) are (because they have a bazillion different queries), you aren’t going to get that from this.

    Reply
    • Wyatt – you’re right, I don’t teach the entirety of performance tuning in this blog post. I really wish I could, but my skills just aren’t quite there yet. Yours might be, though – and I look forward to reading that blog post you write! Sounds awesome.

      Reply
    • I don’t think that is the point of it. I think the point is, “hey payroll, you are using too much CPU and it is interfering with every other department in the organization. you have been restricted to 10% CPU time. fix your queries.”

      Or just dealing with a really horrendous third party app you can’t do anything about and need to keep it from interfering from everything else.

      Even then, in a really busy server, it could be helpful to just know where to start poking. I have an app now that runs so much filth (the entire app is an executable that dynamically constructs sql queries it sends into sql) in my server that the top X worst queries are pretty much always that app and you can’t just pull the low hanging fruit out of blitz cache or whatever

      Reply
  • […] Brent Ozar uses most of Resource Governor: […]

    Reply
  • Alex Friedman
    August 13, 2020 2:33 am

    Ooooh that’s genius. Sometimes you want to know how much a login / app is using up overall, and DMVs don’t capture and retain everything, Query Store too (plus no secondaries), traces will usually only be over a certain threshold to keep them lightweight, so getting complete aggregate data on a busy system can be tough. I love it.

    Reply

Leave a Reply

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

Fill out this field
Fill out this field
Please enter a valid email address.

Menu
{"cart_token":"","hash":"","cart_data":""}