SQL Server Performance – Understanding Glenn Berry Query (CPU per Database)

dmvperformancesql-server-2008-r2

Please, if this is not place to post questions like these, let me know and I will delete it.

Inside the Glenn berry's Diagnostic queries, there is a query to show how much CPU a database is using. This is the query:

-- Get CPU utilization by database (Query 24) (CPU Usage by Database)
WITH DB_CPU_Stats
AS
(SELECT DatabaseID,
        DB_Name(DatabaseID) AS [Database Name],
        SUM(total_worker_time) AS [CPU_Time_Ms]
 FROM sys.dm_exec_query_stats AS qs
 CROSS APPLY (SELECT CONVERT(int, value) AS [DatabaseID] 
              FROM sys.dm_exec_plan_attributes(qs.plan_handle)
             WHERE attribute = N'dbid'
              ) AS F_DB
 GROUP BY DatabaseID)
SELECT ROW_NUMBER() OVER(ORDER BY [CPU_Time_Ms] DESC) AS [CPU Rank],
       [Database Name], [CPU_Time_Ms] AS [CPU Time (ms)], 
       CAST([CPU_Time_Ms] * 1.0 / SUM([CPU_Time_Ms]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CPU Percent]
FROM DB_CPU_Stats
WHERE DatabaseID <> 32767 -- ResourceDB 
ORDER BY [CPU Rank] OPTION (RECOMPILE);

And I would like to know, if this is a query to see databases that are now using more CPU, or is this based with past information?

I'm trying to know what is causing my server to have high CPU use:

enter image description here

Well, in this picture the server is pretty good, but almost always we have 90%+ of CPU usage, and using sp_whoisactive I can't find nothing ( obviously I got a lot of queries, but none of them seems to be hammering the server ).And read\write is pretty low ( everytime ). And thats what i'm having problems to understand. how can a low read/write server be using so much CPU? Does I/O have nothing in common with CPU?

I'm trying to know what database is the heaviest one, to migrate it.

Best Answer

On first glance this looks to me to approximate CPU per database, over the history of sys.dm_exec_query_stats (so usually since the last restart), but only for plans that are currently in the cache. It also relies on a plan cache attribute, dbid, which means that was the context for the query, but not necessarily that that was the database that caused the work. For example, guess where all the CPU gets reported for this query:

USE tempdb;
GO
SELECT CONVERT(DATETIME, CONVERT(CHAR(10), CONVERT(DATE, 
  CONVERT(DATETIME, o.create_date)), 120))
FROM msdb.sys.all_objects AS o
CROSS APPLY model.sys.all_columns AS c;

I'll give you a hint: It's not msdb or model.

So, it should be used as a ballpark, but there are no guarantees that it reflects 100% of reality 100% of the time. The more often you query it (e.g. have some automated job that stores snapshots of it every n minutes), the more accurate it will be, but unless you have applications that treat each database like impenetrable silos, it will still be influenced by database context rather than the actual source of queries and data.