暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如何知道TSQL语句已经运行了多久

SQLServer走起 2020-07-09
545

一个常见的想法是,能否能够知道目前还在运行的TSQL 语句已经运行了多久呢你可以使用SQL server profiler 捕获语句的开始时间,和现在的时间比较就可以知道已经运行多久了。但是Profiler有时候可能带来一些性能影响。下面介绍如何利用DMV 来得到语句已经运行了多久。 

在SQL server  里面有个DMV, sys.dm_exec_requests. 该DMV里面有个 重要的字段start_time, 该字段表示request 开始的时间。一个TSQL Batch就是一个request, 一个request 一般对应一个 task. 如果batch是并发执行,那么对应多个tasks. 我下面的script 不考虑并发执行的情况。在DMV sys.dm_os_workers 里面有个字段task_bound_ms_ticks, 表示工者线程(worker)拿到task 的时间(单位是tick)。 

sys.dm_exec_requests 里面没有包括语句的文本。下面的脚本通过sql_handle 从sys.dm_exec_sql_text 里面得到语句文本,从sys.dm_exec_query_plan里得到执行计划。脚本还输出现在正在执行的是哪一句具体的stmt。这对于一个batch 包括多条语句的时候特别有用,stmt 告诉我们现在执行的是那条具体的SQL语句。

脚本如下:

    DECLARE @ms_per_tick DECIMAL(10, 6); --millisecond per tick

    SELECT @ms_per_tick = 1.0
    * DATEDIFF(MILLISECOND, sqlserver_start_time, GETDATE())
    ( ms_ticks - sqlserver_start_time_ms_ticks )
    FROM sys.[dm_os_sys_info];

    --select @ms_per_tick

    SELECT req.session_id ,
    req.start_time request_start_time ,
    (( SELECT ms_ticks
    FROM sys.dm_os_sys_info ) - workers.task_bound_ms_ticks )
    * @ms_per_tick 'ms_since_task_bound' ,
    DATEDIFF(ms, req.start_time, GETDATE()) 'ms_since_request_start' ,
    tasks.task_state ,
    workers.state worker_state ,
    req.status request_state ,
    st.text ,
    SUBSTRING(
    st.text ,
    ( req.statement_start_offset 2 ) + 1,
    (( CASE req.statement_end_offset
    WHEN-1 THEN DATALENGTH(st.text)
    ELSE req.statement_end_offset
    END - req.statement_start_offset ) 2 ) + 1) AS stmt ,
    qp.query_plan ,
    req.*
    FROM sys.dm_exec_requests req
    LEFT JOIN sys.dm_os_tasks tasks ON tasks.task_address = req.task_address
    LEFT JOIN sys.dm_os_workers workers ON tasks.task_address = workers.task_address
    CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) st
    CROSS APPLY sys.dm_exec_query_plan(req.plan_handle) qp
    WHERE ( req.session_id > 50
    OR req.session_id IS NULL );

    GO

    注意上面的@ms_per_tick用来计算一个tick 相当于多少ms(毫秒), 一般而言,一个tick 基本就是一个毫秒。脚本输出的结果类似如下:


    上面的例子可以看到,spid 52 的batch开始的时间是2011-03-21 16:46:06.817, 已经运行了242610毫秒,batch是”create procedure usp_myi…” , 运行的语句是select * from master..sysprocesses,状态是RUNNING.


    文章转载自:

    http://blogs.msdn.com/b/apgcdsd/archive/2011/05/06/tsql.aspx

    文章经作者授权转载,版权归原文作者所有

    图片来源于网络,侵权必删!



    文章转载自SQLServer走起,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论