有点。看看这个查询:
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 中运行在 MSDB 中“工作”的 SQL 代理作业,但备份单个数据库
它一直在继续。这就是为什么在查询级别而不是数据库级别进行性能调整是有意义的。
在 SQL Server 2008R2 中,Microsoft 引入了性能管理和应用程序管理功能,可以让我们将单个数据库打包到可分发和可部署的 DAC 包中,并且这些功能很有希望让管理单个数据库的性能和它们的应用程序变得更加容易。应用程序。但是,它仍然不能满足您的需求。
有关更多信息,请查看T-SQL repository at Toad World's SQL Server wiki (formerly at SQLServerPedia)。
于 1 月 29 日更新,包括总数而不是平均值。