是否有可能按数据库分类CPU利用率?
我理想地为SQL服务器寻找任务管理器类型接口,但我不想查看每个PID(如taskmgr
)或每个SPID(如spwho2k5
)的CPU利用率,而是想查看每个数据库的总CPU利用率.假设一个SQL实例.
我意识到可以编写工具来收集这些数据并对其进行报告,但我想知道是否有任何工具可以让我看到哪些数据库对sqlservr.exe
CPU负载贡献最大的实时视图.
有点.检查此查询:
SELECT total_worker_time/execution_count AS AvgCPU , total_worker_time AS TotalCPU , total_elapsed_time/execution_count AS AvgDuration , total_elapsed_time AS TotalDuration , (total_logical_reads+total_physical_reads)/execution_count AS AvgReads , (total_logical_reads+total_physical_reads) AS TotalReads , execution_count , SUBSTRING(st.TEXT, (qs.statement_start_offset/2)+1 , ((CASE qs.statement_end_offset WHEN -1 THEN datalength(st.TEXT) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS txt , 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 1 DESC
这将使计划缓存中的查询按照他们用完了多少CPU的顺序.您可以定期运行此命令,例如在SQL代理作业中,并将结果插入表中,以确保数据在重新启动后仍然存在.
当您阅读结果时,您可能会意识到为什么我们无法将这些数据直接关联回单个数据库.首先,单个查询也可以通过这样的技巧隐藏其真正的数据库父级:
USE msdb DECLARE @StringToExecute VARCHAR(1000) SET @StringToExecute = 'SELECT * FROM AdventureWorks.dbo.ErrorLog' EXEC @StringToExecute
查询将在MSDB中执行,但它会从AdventureWorks轮询结果.我们应该在哪里分配CPU消耗?
当你:你变得更糟:
加入多个数据库
在多个数据库中运行事务,锁定工作跨越多个数据库
在MSDB中运行SQL代理作业,在MSDB中"工作",但备份单个数据库
它会一直持续下去.这就是为什么在查询级别而不是数据库级别调整性能是有意义的.
在SQL Server 2008R2中,Microsoft引入了性能管理和应用程序管理功能,这些功能可以让我们将单个数据库打包到可分发和可部署的DAC包中,并且它们具有很好的功能,可以更轻松地管理各个数据库及其应用程序的性能.不过,它仍然无法满足您的需求.
有关更多这些内容,请查看Toad World的SQL Server wiki(以前在SQLServerPedia)上的T-SQL存储库.
在1/29更新,包括总数而不仅仅是平均值.
SQL Server(从2000开始)将安装性能计数器(可从性能监视器或Perfmon中查看).
其中一个计数器类别(来自SQL Server 2005的安装是:) - SQLServer:数据库
每个数据库都有一个实例.但是,可用的计数器不提供CPU%利用率计数器或类似的计数器,尽管有一些速率计数器可用于获得CPU的良好估计.例如,如果您有2个数据库,并且数据库A上测量的速率是20个事务/秒,数据库B上测量的速率是80个传输/秒 - 那么您就会知道A大约占总CPU的20%,并且B贡献其他80%.
这里有一些缺陷,因为假设所有正在完成的工作都是CPU绑定的,当然这与数据库不同.但我相信这将是一个开始.
这是一个查询,它将显示导致高负载的实际数据库.它依赖于可能在低内存情况下频繁刷新的查询缓存(使查询不那么有用).
select dbs.name, cacheobjtype, total_cpu_time, total_execution_count from (select top 10 sum(qs.total_worker_time) as total_cpu_time, sum(qs.execution_count) as total_execution_count, count(*) as number_of_statements, qs.plan_handle from sys.dm_exec_query_stats qs group by qs.plan_handle order by sum(qs.total_worker_time) desc ) a inner join (SELECT plan_handle, pvt.dbid, cacheobjtype FROM ( SELECT plan_handle, epa.attribute, epa.value, cacheobjtype FROM sys.dm_exec_cached_plans OUTER APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa /* WHERE cacheobjtype = 'Compiled Plan' AND objtype = 'adhoc' */) AS ecpa PIVOT (MAX(ecpa.value) FOR ecpa.attribute IN ("dbid", "sql_handle")) AS pvt ) b on a.plan_handle = b.plan_handle inner join sys.databases dbs on dbid = dbs.database_id