As a DBA there may be a time when you want to try and ascertain how much CPU time each of your databases is consuming. This is useful to complement high CPU investigations or to just try and understand which of your databases overall is the highest CPU consumer over time.
The out of the box reporting that Management Studio provides is sadly missing this report so we have to run some T-SQL to extract it.
As with other DMV’s, the statistics produced are only available from the time when the SQL Server was started and can change over the course of the day. It’s important to remember that these are cumulative figures and may not correlate to any current spike in CPU performance caused by some heavy query.
The DMV can only report on the data that is available in the plan cache. If the plan cache is experiencing lots of churn, the report becomes less accurate.
If you want to track this data over time, you will need to capture data at regular intervals and persist it to some kind of logging table or file.
So here is some code to do it:
WITH CPU_Per_Db AS (SELECT dmpa.DatabaseID , DB_Name(dmpa.DatabaseID) AS [Database] , SUM(dmqs.total_worker_time) AS CPUTimeAsMS FROM sys.dm_exec_query_stats dmqs CROSS APPLY (SELECT CONVERT(INT, value) AS [DatabaseID] FROM sys.dm_exec_plan_attributes(dmqs.plan_handle) WHERE attribute = N'dbid') dmpa GROUP BY dmpa.DatabaseID) SELECT [Database] ,[CPUTimeAsMS] ,CAST([CPUTimeAsMS] * 1.0 / SUM([CPUTimeAsMS]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CPUTimeAs{96f5cbaad583fb885ff5d18ecce5734bf1e8596949521e20c290401929518f75}] FROM CPU_Per_Db ORDER BY [CPUTimeAsMS] DESC;
This is what the results looks like on my test instance.
I hope you found this useful 🙂
Greg Bernstein says
Thanks Andy! Great article.
I have a question. Is the CPU time as a percent the percent that SQL Server is using? Or is it the percent that the server on which SQL Server lies is using?
For example, If I have a server that always used 50{96f5cbaad583fb885ff5d18ecce5734bf1e8596949521e20c290401929518f75} of the CPUs. And I have a database, DBX, that always has a CPUTimeAs{96f5cbaad583fb885ff5d18ecce5734bf1e8596949521e20c290401929518f75} value of 50. Does that mean that DBX is always using 25{96f5cbaad583fb885ff5d18ecce5734bf1e8596949521e20c290401929518f75} of the CPUs on the server?
Thanks,
Greg
Andy Hayes says
Hi Greg
Thanks for your comment and great question! 🙂
25{96f5cbaad583fb885ff5d18ecce5734bf1e8596949521e20c290401929518f75} is a good approximation in that example. You do have to take into account that this is cumulative data that has built up since the database server was started and that it is based on what data is available in the plan cache.
In the official MS documentation regarding the DMV it says:
“Returns aggregate performance statistics for cached query plans in SQL Server. The view contains one row per query statement within the cached plan, and the lifetime of the rows are tied to the plan itself. When a plan is removed from the cache, the corresponding rows are eliminated from this view.”