Check Top CPU Queries in 45 Seconds. From Symptoms to Root Clause. The "45 Seconds DBA Series" – What Real DBAs Check First | Part 7 🥇

Before we dive into today's topic, if you missed my previous post you can take a look at Check Memory Grants in 45 Seconds. From Symptoms to Root Clause. The "45 Seconds DBA Series" – What Real DBAs Check First | Part 6 🥇.

👉 If you found this deep-dive helpful, feel free to check out the ads—your support helps me keep creating high-quality SQL Server content for the community.


Identifying high CPU pressure is step one; finding the specific query pulling the trigger is where the real work begins. In this post, I’ll show you how to unmask the top CPU killers in your plan cache in under 45 seconds.

TL;DR

✔️ Worker Time vs. Elapsed Time: High worker time relative to duration indicates a CPU-bound query or heavy parallelism. 🛠️
✔️ Plan Cache Mining: Use sys.dm_exec_query_stats to find the highest cumulative CPU consumers since the last restart. 📦
✔️ Focus on Execution Count: A query that runs 1 million times consuming 10ms is often more dangerous than one running once consuming 10s. 🚀
✔️ Root Cause Analysis: Excessive sorting, hashing, and Scalar UDFs are the usual suspects for CPU spikes. ✔️

Hi SQL SERVER Guys,

In my previous post, we talked about distinguishing between a busy CPU and a backlogged one. But once you've confirmed that your schedulers are indeed choked, you need to find the "Who." As a Senior Expert, I don't believe in guessing. We need to go straight to the Plan Cache. 

If your queries are poorly written—using non-sargable predicates or row-by-row logic—SQL Server has no choice but to burn CPU cycles. Let's find the truth in 45 seconds.

What It Really Is: Worker Time Breakdown

In SQL Server terminology, Worker Time is the actual time the CPU spent executing the query. Elapsed Time is the total time the user waited.

💣 The Problem: When total_worker_time is significantly higher than total_elapsed_time, it's a clear sign of high parallelism (multiple cores working on one query). While parallelism can be good, excessive parallelism on small queries creates a "death by a thousand cuts" scenario for your CPU schedulers.

  • 🔍 sys.dm_exec_query_stats: The DMV that tracks performance metrics for every cached plan.
  • 🔍 Execution Context: Identifying if the CPU load is coming from a few large batches or millions of small, inefficient calls.

🧪 The 45-Second Top CPU Query Script

Use this script to pull the top 10 queries currently eating your CPU alive. This looks at the total worker time across all executions:

SELECT TOP 10
    SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
    ((CASE statement_end_offset 
        WHEN -1 THEN DATALENGTH(st.text) 
        ELSE qs.statement_end_offset END 
            - qs.statement_start_offset)/2) + 1) AS [Query Text],
    qs.execution_count,
    [Avg CPU Time] = qs.total_worker_time / qs.execution_count,
    [Total CPU Time] = qs.total_worker_time,
    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;
  

According to Microsoft Documentation, total_worker_time is measured in microseconds, giving us the precision needed to find even the smallest inefficiencies.

🚀 My REAL Strategy

Stop add CPUs just to have them eaten by Scalar User Defined Functions (UDFs).

  1. Identify UDFs: If you see a Scalar UDF in your top CPU queries, it’s likely forcing row-by-row processing (RBAR). Convert them to Inline Table-Valued Functions (iTVFs).
  2. Check for Excessive Parallelism: If Total CPU Time >> Elapsed Time, look at your Cost Threshold for Parallelism. If it's still at the default of 5, change it to 50 immediately.
  3. The "Plan" is the Key: Click the query_plan link in the results above. Look for Hash Match or Sort operators. These are CPU-intensive. Replacing a Hash Match with a Nested Loop via better indexing can drop CPU usage by 80%.

📢 Support the Blog: Did you find this deep-dive helpful? The ads you see here are selected to reflect your interests. If a partner's offer catches your eye, give it a look! Your engagement helps me continue publishing premium SQL Server content for the community.

Biondi Luca @2026 - Sharing over 25 years of Gained Knowledge for Passion. Share if you like my posts!

Comments

I Post più popolari

Speaking to Sql Server, sniffing the TDS protocol

SQL Server, find text in a Trigger, Stored Procedures, View and Function. Two ways and what ways is better

SQL Server, Avoid that damn Table Spool!