簡體   English   中英

獲取用戶或應用程序查詢的長時間運行查詢

[英]Get Long Running Queries For Users Or Applications Queries

我最近閱讀了這篇完美的文章:

如何通過執行計划找到運行時間最長的查詢 - 本周面試問題 #098

它返回系統調用查詢(內部 SQL 服務器工作)。

在此處輸入圖像描述

是否可以過濾這些查詢並僅返回用戶或應用程序調用查詢?

謝謝。

你是那里的 1/2 方式:你需要捕獲有關正在運行的歷史信息。 您在問題 sys.dm_exec_query_stats 中查詢的內容是累積和匯總的統計信息,這些統計信息不是由保證仍連接到服務器的會話/連接,以便您識別它來自何處。 為了克服這個問題,您需要捕獲歷史信息。 有很多方法可以做到這一點。 我建議使用 SQL 服務器代理作業和 tSQL 步驟。 您需要按計划運行類似於以下查詢的內容並將數據記錄到歷史表中。 然后,您可以將 sql_handle 上的原始查詢交叉應用或加入到您從 SQL 服務器代理作業保持最新的歷史表中

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 服務器代理作業按某個計划運行,將上述查詢結果放入 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

我已修改查詢以獲取用戶/應用程序調用查詢。 您可以從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

這是不可能的,現在沒有 DMV 保存此信息。

順便說一句,什么是“應用程序調用查詢”? 你指的是工作嗎?

正如其他人已經寫過的那樣,您唯一的選擇是將此信息與觸發器、作業或外部應用程序一起保存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM