数据库的CPU使用率?

时间:2020-03-05 18:43:31  来源:igfitidea点击:

是否可以按数据库细分CPU利用率?

理想情况下,我正在寻找SQL Server的任务管理器类型的接口,但我不想查看每个PID(例如taskmgr)或者每个SPID(例如spwho2k5)的CPU使用率,而是要查看CPU的总使用率每个数据库。假设一个SQL实例。

我意识到可以编写工具来收集这些数据并进行报告,但是我想知道是否有任何工具可以让我实时查看哪些数据库对sqlservr.exe CPU负载的贡献最大。

解决方案

回答

SQL Server(从2000开始)将安装性能计数器(可从Performance Monitor或者Perfmon查看)。

计数器类别之一(从SQL Server 2005安装为:)
SQLServer:数据库

每个数据库有一个实例。尽管有一些速率计数器,但是可用的计数器不提供CPU%利用率计数器或者类似的计数器,我们可以使用它们来很好地估计CPU。例如,如果我们有2个数据库,并且数据库A的测量速率为每秒20个事务/秒,而数据库B的测量速率为80事务/秒,那么我们将知道A大约占总CPU的20%,而B贡献了其他80%。

这里存在一些缺陷,因为这假设所有已完成的工作都受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 Agent作业中一样定期运行此命令,并将结果插入表中以确保数据在重启后仍然存在。

阅读结果时,我们可能会意识到为什么我们不能将数据直接关联回单个数据库。首先,单个查询还可以通过执行以下技巧来隐藏其真正的数据库父级:

USE msdb
DECLARE @StringToExecute VARCHAR(1000)
SET @StringToExecute = 'SELECT * FROM AdventureWorks.dbo.ErrorLog'
EXEC @StringToExecute

该查询将在MSDB中执行,但会查询AdventureWorks的结果。我们应该在哪里分配CPU消耗?

当我们:

  • 多个数据库之间的联接
  • 在多个数据库中运行事务,锁定工作跨越多个数据库
  • 在MSDB中运行可以在MSDB中"工作"的SQL Agent作业,但备份单个数据库

它会一直持续下去。这就是为什么在查询级别而不是数据库级别进行性能调整很有意义的原因。

在SQL Server 2008R2中,Microsoft引入了性能管理和应用程序管理功能,这些功能使我们可以将单个数据库打包到可分发和可部署的DAC包中,它们有望使功能更易于管理单个数据库及其应用程序的性能。不过,它仍然无法满足需求。

有关更多信息,请访问Toad World的SQL Server Wiki(以前为SQLServerPedia)上的T-SQL存储库。

在1/29上进行了更新,以包括总数而不是平均值。

回答

我认为问题的答案是否定的。

问题在于,一台计算机上的一项活动可能导致多个数据库上的负载。如果我有一个正在从配置DB读取,登录到日志记录DB以及根据类型将事务移入和移出各个DB的进程,该如何划分CPU使用率?

我们可以将CPU利用率除以事务负载,但这又是一个粗略的指标,可能会误导我们。例如,如何将事务日志传送从一个数据库分配到另一个数据库? CPU负载在读取还是写入中?

我们最好查看计算机的事务处理速率及其引起的CPU负载。我们还可以分析存储过程,并查看其中是否花费了过多的时间。但是,这不会为我们提供所需的答案。

回答

看一下SQL Sentry。它可以满足所有需求。

问候,
利文

回答

我们是否看过SQL事件探查器?

使用标准的" T-SQL"或者"存储过程"模板,调整字段以按数据库ID进行分组(我认为我们必须使用数字,没有获得数据库名称,但是使用exec sp_databases很容易找出来获取列表)

运行一段时间,我们将获得总CPU计数/磁盘IO /等待等。这可以为我们提供每个数据库使用的CPU比例。

如果我们同时监视PerfMon计数器(将数据记录到SQL数据库),并且对SQL Profiler进行相同的操作(记录到数据库),则可以将两者关联起来。

即使这样,它也应该给我们足够的线索来说明哪个DB值得更详细地研究。然后,仅使用该数据库ID再次执行相同的操作,并查找最昂贵的SQL /存储过程。