我最近阅读了这篇完美的文章:
如何通过执行计划找到运行时间最长的查询 - 本周面试问题 #098
它返回系统调用查询(用于内部 SQL Server 工作)。
是否可以过滤这些查询并仅返回用户或应用程序调用查询?
谢谢。
我最近阅读了这篇完美的文章:
如何通过执行计划找到运行时间最长的查询 - 本周面试问题 #098
它返回系统调用查询(用于内部 SQL Server 工作)。
是否可以过滤这些查询并仅返回用户或应用程序调用查询?
谢谢。
你是那里的 1/2 方式:你需要捕获有关正在运行的历史信息。您在问题 sys.dm_exec_query_stats 中查询的内容是累积和汇总的统计信息,这些统计信息不是由保证仍连接到服务器的会话/连接,以便您识别它来自何处。为了克服这个问题,您需要捕获历史信息。有很多方法可以做到这一点。我建议使用带有 tSQL 步骤的 SQL Server 代理作业。您需要按计划运行类似于以下查询的内容并将数据记录到历史表中。然后,您可以将 sql_handle 上的原始查询交叉应用或加入到您从 SQL Server 代理作业中保持最新的历史表中
select
r.session_id,
s.login_name,
c.client_net_address,
s.host_name,
s.program_name,
r.sql_handle,
r.start_time
from sys.dm_exec_requests r
inner join sys.dm_exec_sessions s
on r.session_id = s.session_id
left join sys.dm_exec_connections c
on r.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
因此,如果您有一个 SQL Server 代理作业按某个计划运行,将上述查询结果放入 DBA.dbo.QueryHistory,您可以将原始查询从 sqlauthority 更改为类似这样的内容,以获取与查询相关联的用户名:
SELECT TOP 10
t.TEXT QueryName,
s.execution_count AS ExecutionCount,
s.max_elapsed_time AS MaxElapsedTime,
ISNULL(s.total_elapsed_time / 1000 / NULLIF(s.execution_count, 0), 0) AS AvgElapsedTime,
s.creation_time AS LogCreatedOn,
ISNULL(s.execution_count / 1000 / NULLIF(DATEDIFF(s, s.creation_time, GETDATE()), 0), 0) AS FrequencyPerSec
,query_plan
FROM sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_query_plan( s.plan_handle ) u
CROSS APPLY sys.dm_exec_sql_text( s.plan_handle ) t
outer apply (
select top 1 login_name
from DBA.dbo.QueryHistory QH
where QH.sql_handle = s.sql_handle
)
ORDER BY MaxElapsedTime DESC
这是不可能的,现在没有 DMV 保存此信息。
顺便说一句,什么是“应用程序调用查询”?你指的是工作吗?
正如其他人已经写过的那样,您唯一的选择是将此信息与触发器、作业或外部应用程序一起保存。
我已修改查询以获取用户/应用程序调用查询。您可以从sys.dm_exec_sessions
SELECT TOP 10
ss.program_name, --Name of the client program
ss.host_name, -- Workstation of client session
ss.client_interface_name, -- Driver used by client to communicate
ss.login_name, -- Client login name
t.TEXT QueryName,
s.execution_count AS ExecutionCount,
s.max_elapsed_time AS MaxElapsedTime,
ISNULL(s.total_elapsed_time / 1000 / NULLIF(s.execution_count, 0), 0) AS AvgElapsedTime,
s.creation_time AS LogCreatedOn,
ISNULL(s.execution_count / 1000 / NULLIF(DATEDIFF(s, s.creation_time, GETDATE()), 0), 0) AS FrequencyPerSec
,query_plan
FROM sys.dm_exec_query_stats s
INNER JOIN sys.dm_exec_requests as r
on r.plan_handle = s.plan_handle
INNER JOIN sys.dm_exec_sessions AS ss
ON ss.session_id = r.session_id
CROSS APPLY sys.dm_exec_query_plan( s.plan_handle ) u
CROSS APPLY sys.dm_exec_sql_text( s.plan_handle ) t
WHERE ss.program_name is not null -- not internal session
ORDER BY MaxElapsedTime DESC