我有以下查询,它告诉我我负责的数据库中查询的状态(尽管我不是 DBA)。
SELECT
T3.FullStatement as FullSQLStatement
,T3.ExecutingStatement
,req.session_id as SessionId
,T2.login_name as LoginName
,command as SQLCommand
,start_time as StartTime
,DateDiff(MINUTE,start_time,GetDate()) as ElapsedTimeMinutes
,req.status as QueryStatus
,req.wait_type as WaitType
,req.wait_time as WaitTimeMs
,blocking_session_id as BlockingSessionId
,req.row_count as [RowCount]
,req.cpu_time as CpuTimeMs
,req.total_elapsed_time as TotalElapsedTimeMs
,SubString(sqltext.TEXT,req.statement_start_offset,req.statement_end_offset-req.statement_start_offset)
FROM sys.dm_exec_requests req
Inner Join sys.dm_exec_sessions T2 ON T2.session_id = req.session_id
Cross Apply dbo.GetExecutingSQLStatement (req.session_id) T3
Cross Apply sys.dm_exec_sql_text(sql_handle) AS sqltext
where req.database_id = 5
Order By 6 Desc
Run Code Online (Sandbox Code Playgroud)
它生成的输出部分如下所示:
尽管它在我包含的示例中没有很好地显示,但 start_time 是完整语句的开始时间,而不是语句的执行部分。有什么地方可以获取执行部分的开始时间以及完整语句的开始时间。这对我很重要,因为很明显,一个完整的语句可能有许多单独的查询。
目前这似乎不是一个可能的价值,这是不幸的,因为这似乎是一个方便的价值。
好的,我确实找到了(大部分)。sys.dm_exec_query_stats DMV 中有一个last_execution_time字段,尽管该 DMV 带有以下警告:
如果服务器上当前正在执行工作负载,则对sys.dm_exec_query_stats的初始查询可能会产生不准确的结果。可以通过重新运行查询来确定更准确的结果。
此外,我不确定 的值如何last_execution_time受到跨多个会话的完全相同 SQL 的多次并发执行的影响,因为sys.dm_exec_query_stats是每个查询批处理,而不是每个会话。
以下是我到目前为止所拥有的。也许我有点想清理一件事,但这应该已经说明了批处理中的第一个查询,该查询不会有相应的条目,sys.dm_exec_query_stats因为它在当前之后被填充(理想情况下,但并不总是及时)语句/查询完成。它似乎适用于单查询批处理,所以试试吧。
SELECT req.session_id AS [SessionID],
req.start_time AS [BatchStartTime],
req.total_elapsed_time as [BatchMilliseconds], --[TotalElapsedTimeMs],
CASE WHEN stat.last_execution_time IS NOT NULL THEN
DATEADD(MILLISECOND,
(stat.last_elapsed_time / 1000.0),
stat.last_execution_time)
ELSE req.start_time END AS [StatementStartTime],
DATEDIFF(MILLISECOND,
CASE WHEN stat.last_execution_time IS NOT NULL THEN
DATEADD(MILLISECOND, (stat.last_elapsed_time / 1000.0),
stat.last_execution_time)
ELSE req.start_time END, GETDATE()) AS [StatementMilliseconds],
T2.login_name AS [LoginName],
req.command AS [SQLCommand],
req.[status] AS [QueryStatus],
req.wait_type AS [WaitType],
req.wait_time AS [WaitTimeMs],
blocking_session_id AS [BlockingSessionId],
req.row_count AS [RowCount],
req.cpu_time AS [CpuTimeMs],
sqltext.[text] AS [QueryBatch],
SUBSTRING(sqltext.[text],
req.statement_start_offset / 2,
CASE req.statement_end_offset
WHEN -1 THEN DATALENGTH(sqltext.[text])
ELSE (req.statement_end_offset - req.statement_start_offset) / 2
END) AS [CurrentQuery]
FROM sys.dm_exec_requests req
INNER JOIN sys.dm_exec_sessions T2
ON T2.session_id = req.session_id
LEFT JOIN sys.dm_exec_query_stats stat
ON stat.[sql_handle] = req.[sql_handle]
AND stat.statement_end_offset = (req.statement_start_offset - 2)
CROSS APPLY sys.dm_exec_sql_text(req.[sql_handle]) sqltext
-- WHERE req.session_id = 56
ORDER BY req.start_time;
Run Code Online (Sandbox Code Playgroud)
我已与您的查询(略有修改)测试和下面的SQL在另一个选项卡/会话中运行(在TOP(1),TOP(2)等,以及10.1,10.2在等WAITFOR时间,使之很容易看到其中的语句正在处理查看当前时语句字段):
SELECT GETDATE() AS [StartTime];
GO
SELECT TOP(1) [name] FROM sys.objects;
WAITFOR DELAY '00:00:10.1';
SELECT TOP(2) [name] FROM sys.objects;
WAITFOR DELAY '00:00:10.2';
SELECT TOP(3) [name] FROM sys.objects;
WAITFOR DELAY '00:00:10.3';
SELECT TOP(4) [name] FROM sys.objects;
WAITFOR DELAY '00:00:10.4';
Run Code Online (Sandbox Code Playgroud)
然后只需多次运行您的查询,很明显,dm_exec_requests.start_time和dm_exec_sessions.last_request_start_time是:
我确实尝试通过 获取执行计划CROSS APPLY sys.dm_exec_text_query_plan(req.plan_handle, req.statement_end_offset, req.statement_end_offset) tplan,但这NULL并不是很有帮助。
为了测试您的查询,我必须删除前两列和对该dbo.GetExecutingSQLStatement函数的引用。这可能是您也可以摆脱的,因为您已经通过CROSS APPLY sys.dm_exec_sql_text(req.[sql_handle]). 您只需要进行以下三项更改:
T3.FullStatement (选择字段#1)变成 sqltext.[text]
T3.ExecutingStatement (选择字段#2)变成 SUBSTRING(sqltext.[text], req.statement_start_offset / 2, CASE req.statement_end_offset WHEN -1 THEN LEN(sqltext.[text]) ELSE (req.statement_end_offset - req.statement_start_offset) / 2 END)
删除SUBSTRING(您当前的最后一个字段)。如果您仔细查看SUBSTRING我直接在上面建议的内容,它本质上就是您最后所拥有的内容,希望它可以纠正两个错误:
statement_end_offset是-1和你的子得到一个错误但我离题了。
| 归档时间: |
|
| 查看次数: |
1222 次 |
| 最近记录: |