web-dev-qa-db-ja.com

SQL Server 2008 R2 DMVに関する質問

Dm_exec_query_stats DMVからの論理読み取りの合計に基づいて上位10件のクエリを取得するクエリがあります。

SELECT TOP 10 
    SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
    ((CASE qs.statement_end_offset
    WHEN -1 THEN DATALENGTH(qt.TEXT)
    ELSE qs.statement_end_offset
    END - qs.statement_start_offset)/2)+1),
db_name(qt.dbid) as db_name,
qs.execution_count,
qs.total_logical_reads,
qs.total_worker_time,
qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
SUBSTRING(CONVERT(varchar(19),qs.last_execution_time),1,19)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.total_logical_reads DESC

クエリは、クエリの送信元または送信先のデータベースの名前を除いて、要求されたすべての情報を返します。 dm_exec_sql_textとdm_exec_query_planのどちらを使用しても、結果は同じです。

db_name(qt.dbid)as db_name dm_exec_sql_text

または

db_name(qp.dbid)as db_name dm_exec_query_plan

どちらもデータベース名としてNULLまたはtempdbを返します。

[レポート]-> [平均IO別のパフォーマンス上位クエリ]を選択すると、同じ問題が発生します。

enter image description here

データベース名が空です。

ただし、クエリプランをクエリに追加し、SSMSでクエリプランを開くと、さまざまなインデックスシーク、スキャン、またはRIDルックアップにカーソルを合わせると、元のデータベースの名前を確認できます。

enter image description here

Mssqlsystemresourceやtrackitデータベースなど、クエリプランで参照されるデータベースがいくつかあることに気付きました

クエリプランがクエリの影響を受けるデータベースの名前をトップ10リストに表示できた場合、DMVを使用してそれらのデータベースの名前を取得できるはずです。

上位10個のクエリを変更して、各クエリのデータベースの名前を取得するにはどうすればよいですか?

または、CPU/IO /メモリ使用量の上位10件のクエリを取得して、上位10件のデータベース名を取得するためのより良い方法はありますか?

7
Craig Efrein
use dbx;
select foo
from db1.dbo.table
join db2.dbo.table on condition
where some_function();

このクエリは大量のCPUを消費し、大量のメモリ許可を要求しました。どのデータベースに?必要な情報は概念として存在しません。洞察の知識と後知恵を持つ人間として、CPUの75%がdb1に起因し、15%がdb2に起因する理由を説明できるでしょう。しかし、最終的にはデータベースにクエリを割り当てることができます。一部の(大部分の)クエリがデータベース内に100%含まれているという事実は、すべてのクエリリソースをデータベースに確定的に割り当てることができることを意味しません。

ただし、実際的な方法は、投稿で行ったことを正確に自動化するのが比較的簡単です。計画を調べて すべての物理アクセスオペレーターの場所を特定 し、この情報を使用してクエリリソースをDBに割り当てます。

with xmlnamespaces (default 'http://schemas.Microsoft.com/sqlserver/2004/07/showplan')
select x.value(N'@NodeId',N'int') as NodeId
    , x.value(N'@PhysicalOp', N'sysname') as PhysicalOp
    , x.value(N'@LogicalOp', N'sysname') as LogicalOp
    , ox.value(N'@Database',N'sysname') as [Database]
    , ox.value(N'@Schema',N'sysname') as [Schema]
    , ox.value(N'@Table',N'sysname') as [Table]
    , ox.value(N'@Index',N'sysname') as [Index]
    , ox.value(N'@IndexKind',N'sysname') as [IndexKind]
    , x.value(N'@EstimateRows', N'float') as EstimateRows
    , x.value(N'@EstimateIO', N'float') as EstimateIO
    , x.value(N'@EstimateCPU', N'float') as EstimateCPU
    , x.value(N'@AvgRowSize', N'float') as AvgRowSize
    , x.value(N'@TableCardinality', N'float') as TableCardinality
    , x.value(N'@EstimatedTotalSubtreeCost', N'float') as EstimatedTotalSubtreeCost
    , x.value(N'@Parallel', N'tinyint') as DOP
    , x.value(N'@EstimateRebinds', N'float') as EstimateRebinds
    , x.value(N'@EstimateRewinds', N'float') as EstimateRewinds
    , st.*
    , pl.query_plan
from sys.dm_exec_query_stats as st
cross apply sys.dm_exec_query_plan (st.plan_handle) as pl
cross apply pl.query_plan.nodes('//RelOp[./*/Object/@Database]') as op(x)
cross apply op.x.nodes('./*/Object') as ob(ox)
8
Remus Rusanu