このような質問を投稿する場所でない場合は、お知らせください。削除します。
Glenn berryの Diagnosticクエリ の内部には、データベースが使用しているCPUの量を示すクエリがあります。これはクエリです:
-- Get CPU utilization by database (Query 24) (CPU Usage by Database)
WITH DB_CPU_Stats
AS
(SELECT DatabaseID,
DB_Name(DatabaseID) AS [Database Name],
SUM(total_worker_time) AS [CPU_Time_Ms]
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY (SELECT CONVERT(int, value) AS [DatabaseID]
FROM sys.dm_exec_plan_attributes(qs.plan_handle)
WHERE attribute = N'dbid'
) AS F_DB
GROUP BY DatabaseID)
SELECT ROW_NUMBER() OVER(ORDER BY [CPU_Time_Ms] DESC) AS [CPU Rank],
[Database Name], [CPU_Time_Ms] AS [CPU Time (ms)],
CAST([CPU_Time_Ms] * 1.0 / SUM([CPU_Time_Ms]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CPU Percent]
FROM DB_CPU_Stats
WHERE DatabaseID <> 32767 -- ResourceDB
ORDER BY [CPU Rank] OPTION (RECOMPILE);
そして、私が知りたいのは、これがnow
がより多くのCPUを使用しているデータベースを表示するクエリであるか、または過去の情報に基づいていますか?
サーバーのCPU使用率が高くなっている原因を調べようとしています。
この図ではサーバーはかなり良いですが、ほとんどの場合、CPU使用率が90%以上あり、sp_whoisactive
何も見つけることができません(明らかに多くのクエリを取得しましたが、それらのどれもがサーバーに影響を与えているようには見えません)。そして、それは私が理解するのに問題を抱えているものです。低読み取り/書き込みサーバーがどのように多くのCPUを使用しているのでしょうか。 I/OにはCPUとの共通点はありませんか?
私はそれを移行するために、どのデータベースが最も重いのかを知りたいと思っています。
一見すると、これはsys.dm_exec_query_stats
の履歴(通常は最後の再起動以降)に基づいて、データベースあたりのCPUを概算するように見えますが、現在キャッシュ内にあるプランについてのみです。また、プランキャッシュ属性dbid
にも依存します。これは、クエリのコンテキストであったことを意味しますが、作業を引き起こしたデータベースであるとは限りません。たとえば、このクエリですべてのCPUが報告される場所を推測します。
USE tempdb;
GO
SELECT CONVERT(DATETIME, CONVERT(CHAR(10), CONVERT(DATE,
CONVERT(DATETIME, o.create_date)), 120))
FROM msdb.sys.all_objects AS o
CROSS APPLY model.sys.all_columns AS c;
ヒントを差し上げます:msdb
やmodel
ではありません。
したがって、それは球場として使用する必要がありますが、100%現実の100%を反映するという保証はありません。クエリを頻繁に実行する(たとえば、n分ごとにそのスナップショットを保存する自動ジョブがある)と、より正確になりますが、各データベースを侵入不可能なサイロのように扱うアプリケーションがない限り、データベースコンテキストの影響を受けますクエリとデータの実際のソースではなく。
sys.dm_exec_query_stats
は、SQL Serverで キャッシュされたクエリプランの集計パフォーマンス統計 を返します。プランがキャッシュから削除されると、対応する行がこのビューから削除されます。
ここでの含意は、この動的管理ビューが要件を部分的にのみ満たすことです。アーロンが彼の回答で述べたように、特定のデータベースへの帰属はクエリのコンテキストに敏感です。また、プランがあまり長くキャッシュされていない場合、このクエリを実行するときにプランがキャッシュにない可能性があるため、レポートされません。システムが動的クエリを実行している場合、プランキャッシュに使い捨てプランが殺到している可能性があり、それがこのパフォーマンスメトリックの信頼性を大幅に制限している可能性があります。
「アドホックワークロードの最適化」がオンになっていますか?次のクエリで確認します。
SELECT c.name
, c.value_in_use
FROM sys.configurations c
WHERE c.name = 'optimize for ad hoc workloads';
次のクエリを使用して、プランキャッシュが時間の経過とともにどのように変化しているかを確認できます。
BEGIN TRY
CREATE TABLE #PC1
(
refcounts INT
, usecounts INT
, size_in_bytes INT
, memory_object_address varbinary(32)
, cacheobjtype VARCHAR(255)
, objtype VARCHAR(255)
, plan_handle VARBINARY(32)
, [dbid] INT
, objectid INT
, query_plan XML
);
END TRY
BEGIN CATCH
END CATCH
BEGIN TRY
CREATE TABLE #PC2
(
refcounts INT
, usecounts INT
, size_in_bytes INT
, memory_object_address varbinary(32)
, cacheobjtype VARCHAR(255)
, objtype VARCHAR(255)
, plan_handle VARBINARY(32)
, [dbid] INT
, objectid INT
, query_plan XML
);
END TRY
BEGIN CATCH
END CATCH
TRUNCATE TABLE #PC1;
TRUNCATE TABLE #PC2;
INSERT INTO #PC1
(
refcounts
, usecounts
, size_in_bytes
, memory_object_address
, cacheobjtype
, objtype
, plan_handle
, [dbid]
, objectid
, query_plan
)
SELECT
refcounts
, usecounts
, size_in_bytes
, memory_object_address
, cacheobjtype
, objtype
, plan_handle
, [dbid]
, objectid
, query_plan
FROM sys.dm_exec_cached_plans decp
CROSS APPLY sys.dm_exec_query_plan(decp.plan_handle) t
ORDER BY decp.usecounts DESC;
WAITFOR DELAY '00:01:00';
INSERT INTO #PC2
(
refcounts
, usecounts
, size_in_bytes
, memory_object_address
, cacheobjtype
, objtype
, plan_handle
, [dbid]
, objectid
, query_plan
)
SELECT
refcounts
, usecounts
, size_in_bytes
, memory_object_address
, cacheobjtype
, objtype
, plan_handle
, [dbid]
, objectid
, query_plan
FROM sys.dm_exec_cached_plans decp
CROSS APPLY sys.dm_exec_query_plan(decp.plan_handle) t
ORDER BY decp.usecounts DESC;
SELECT QueryPlan = pc1.query_plan
, UseCount = pc2.usecounts - pc1.usecounts
, PlanSize = pc1.size_in_bytes
, CacheType = pc1.cacheobjtype
, objType = pc1.objtype
, DatabaseID = pc1.dbid
FROM #PC1 pc1
INNER JOIN #PC2 pc2 ON pc1.plan_handle = pc2.plan_handle
WHERE pc2.usecounts - pc1.usecounts > 0
ORDER BY (pc2.usecounts - pc1.usecounts);
SELECT QueryPlan = pc1.query_plan
, UseCount = pc1.usecounts
, PlanSize = pc1.size_in_bytes
, CacheType = pc1.cacheobjtype
, objType = pc1.objtype
, DatabaseID = pc1.dbid
FROM #PC1 pc1
WHERE NOT EXISTS
(
SELECT 1
FROM #PC2 pc2
WHERE pc2.plan_handle = pc1.plan_handle
)
ORDER BY (pc1.usecounts);
SELECT QueryPlan = pc2.query_plan
, UseCount = pc2.usecounts
, PlanSize = pc2.size_in_bytes
, CacheType = pc2.cacheobjtype
, objType = pc2.objtype
, DatabaseID = pc2.dbid
FROM #PC2 pc2
WHERE NOT EXISTS
(
SELECT 1
FROM #PC1 pc1
WHERE pc1.plan_handle = pc2.plan_handle
)
ORDER BY (pc2.usecounts);
このクエリはプランキャッシュを2回調べ、その間に1分間待機します。次に、3つの結果セットを返します。
最初の結果セットが2番目の結果セットよりもはるかに少ないプランの数を示している場合は、サーバーのキャッシュ領域が絶えず不足していることを示しています。これは明らかに、Glennのクエリが期待するほど信頼できるものではないことを示しています。