ある種。このクエリをチェックしてください:
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パックにパッケージ化できるパフォーマンス管理およびアプリ管理機能を導入しました。これらの機能は、個々のデータベースとそのアプリケーションのパフォーマンスをより簡単に管理できるようにする有望な機能です。それでも、あなたが探していることはできません。
これらの詳細については、ToadWorldのSQLServerwiki(以前のSQLServerPedia)のT-SQLリポジトリ 。
1/29に更新され、平均だけでなく総数が含まれるようになりました。