Freigeben über


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

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

在SQL
server 2005/SQL server 2008 里面有个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.

Comments

  • Anonymous
    November 15, 2011
    sqlserver_start_time跟sqlserver_start_time_ms_ticks只有SQL Server 2008以上的版本才有