Cra*_*ein 7 sql-server 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
Run Code Online (Sandbox Code Playgroud)
查询返回所有请求的信息,除了查询来自或指向的数据库的名称。无论我使用 dm_exec_sql_text 还是 dm_exec_query_plan 结果都是一样的。
db_name(qt.dbid) 作为 db_name dm_exec_sql_text
或者
db_name(qp.dbid) 作为 db_name dm_exec_query_plan
两者都返回 NULL 或 tempdb 作为数据库名称。
选择 Reports -> Performance Top Queries by Average IO 时会出现同样的问题。

数据库名称为空。
但是,如果我将查询计划添加到查询中,然后在 SSMS 中打开查询计划,我可以通过将鼠标悬停在各种索引查找、扫描或 RID 查找上来查看原始数据库的名称。

我注意到查询计划中引用了多个数据库,例如 mssqlsystemresource 和 trackit 数据库
如果查询计划能够在我的前 10 个列表中显示受查询影响的一个或多个数据库的名称,那么我应该能够使用 DMV 获取这些数据库的名称是有道理的。
如何修改前 10 个查询以检索每个查询的数据库名称?
或者有没有更好的方法来按 CPU/IO/内存使用情况获取前 10 个查询并获取前 10 个中每个的数据库名称或名称?
use dbx;
select foo
from db1.dbo.table
join db2.dbo.table on condition
where some_function();
Run Code Online (Sandbox Code Playgroud)
此查询消耗大量 CPU 并请求大量内存授予。在哪个数据库?您想要的信息根本不作为概念存在。作为具有洞察力知识和事后利益的人,您可能能够解释为什么 75% 的 CPU 是由于 db1 而 15% 是由于 db2。但最终您只能将查询分配给数据库。某些(好的,大多数)查询 100% 包含在数据库中的事实并不意味着所有查询资源都可以确定性地分配给数据库。
然而,对于实际的方法来说,完全自动化您在帖子中所做的工作是相对简单的:检查计划并确定所有物理访问操作员的位置,并使用此信息将查询资源分配给数据库。
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)
Run Code Online (Sandbox Code Playgroud)