当SQL Server 引擎接收到用户发出的查询请求时,SQL Server执行优化器将查询请求(Request)和Task绑定,并为Task分配一个Workder,SQL Server申请操作系统的进程(Thread)来执行Worker。如果以并行的方式执行Request,SQL Server根据Max DOP(Maximum Degree Of Parallelism) 配置选项创建新的Child Tasks,SQL Server将Request和多个Task绑定;例如,如果Max DOP=8,那么将会存在 1个Master Task和 8 个Child Tasks。每个Task绑定到一个Worker中,SQL Server引擎将分配相应数量的Worker来执行Tasks。

一,查看正在执行的请求(Request)

使用 sys.dm_exec_requests 返回正在执行的查询请求(Request)关联的查询脚本,阻塞和资源消耗。

1,查看SQL Server正在执行的查询语句

  • sql_handle,statement_start_offset,statement_end_offset ,能够用于查看正在执行的查询语句;
  • 字段plan_handle,用于查看查询语句的执行计划;
  • 字段 command 用于表示正在被处理的Command的当前的类型:SELECT,INSERT,UPDATE,DELETE,BACKUP LOG ,BACKUP DATABASE,DBCC,FOR;

2,查看阻塞(Block)的语句

  • 字段 wait_type:如果Request正在被阻塞,字段wait_type 返回当前的Wait Type
  • 字段 last_wait_type:上一次阻塞的Wait Type
  • 字段 wait_resource:当前阻塞的Request正在等待的资源
  • 字段 blocking_session_id :将当前Request阻塞的Session

3,内存,IO,CPU消耗统计

  • 字段 granted_query_memory: 授予内存的大小,Number of pages allocated to the execution of a query on the request
  • 字段 cpu_time,total_elapsed_time :消耗的CPU时间和总的消耗时间
  • 字段 reads,writes,logical_reads:物理Read,逻辑Write 和逻辑Read的次数

二,查看SQL Server 当前正在执行的SQL查询语句

在进行故障排除时,使用DMV:sys.dm_exec_requests 查看SQL Server当前正在执行的查询语句:

select   db_name(r.database_id) as db_name
,s.group_id
,r.session_id
,r.blocking_session_id as blocking
,s.login_name
,r.wait_type as current_wait_type
,r.wait_resource
,r.last_wait_type
,r.wait_time/1000 as wait_s
,r.status as request_status
,r.command
,r.cpu_time
,r.reads
,r.writes
,r.logical_reads
,r.total_elapsed_time
,r.start_time
,s.status as session_status
,substring( st.text,
r.statement_start_offset/2+1,
( case when r.statement_end_offset = -1
then len(convert(nvarchar(max), st.text))
else (r.statement_end_offset - r.statement_start_offset)/2
end
)
) as individual_query
from sys.dm_exec_requests r
inner join sys.dm_exec_sessions s
on r.session_id=s.session_id
outer APPLY sys.dm_exec_sql_text(r.sql_handle) as st
where ((r.wait_type<>'MISCELLANEOUS' and r.wait_type <> 'DISPATCHER_QUEUE_SEMAPHORE' ) or r.wait_type is null)
and r.session_id>50
and r.session_id<>@@spid
order by r.session_id asc

1,在故障排除时,可以过滤掉一些无用的wait type 和当前Session:

  • @@SPID 表示当前的spid,一般来说,SPID<=50是system session,SPID>50的是User Session;
  • WaitType 为'MISCELLANEOUS' 时,不用于标识任何有效的Wait,仅仅作为默认的Wait;
  • WaitType 为‘DISPATCHER_QUEUE_SEMAPHORE’时,表示当前的Thread在等待处理更多的Work,如果Wait Time增加,说明Thread调度器(Dispatcher)非常空闲;
  • 关于WaitType ,请查看 The SQL Server Wait Type Repository

2,查看request执行的SQL查询语句

sql_handle 字段表示当前查询语句的句柄(handle),将该字段传递给sys.dm_exec_sql_text函数,将获取Request执行的SQL语句,SQL Server对某些包含常量的查询语句自动参数化(“Auto-parameterized”),获取的SQL 查询语句格式如下,SQL Server在查询语句的开头增加参数声明:

(@P1 int,@P2 int,@P3 datetime2(7),@P4 datetime2(7))
WITH CategoryIDs AS
(SELECT B.CategoryID,
.....

两个字段:stmt_start和stmt_end,用于标识参数声明的开始和结尾的位置,使用这两个字段,将参数声明剥离,返回SQL Server执行的查询语句。

3,阻塞

字段 blocking_session_id :阻塞当前Request的Session,但排除0,-2,-3,-4 这四种ID值:

  • If this column is 0, the request is not blocked, or the session information of the blocking session is not available (or cannot be identified).
  • -2 = The blocking resource is owned by an orphaned distributed transaction.
  • -3 = The blocking resource is owned by a deferred recovery transaction.
  • -4 = Session ID of the blocking latch owner could not be determined at this time because of internal latch state transitions.

三,查看SQL Server实例中活动的Task

使用DMV:sys.dm_os_tasks 查看当前实例中活动的Task

1,字段 task_state,标识Task的状态

  • PENDING: Waiting for a worker thread.
  • RUNNABLE: Runnable, but waiting to receive a quantum.
  • RUNNING: Currently running on the scheduler.
  • SUSPENDED: Has a worker, but is waiting for an event.
  • DONE: Completed.
  • SPINLOOP: Stuck in a spinlock.

2,挂起的IO(Pending)

  • pending_io_count
  • pending_io_byte_count
  • pending_io_byte_average

3,关联的Request和Worker(associated)

  • request_id : ID of the request of the task.
  • worker_address :Memory address of the worker that is running the task. NULL = Task is either waiting for a worker to be able to run, or the task has just finished running.

4, Task Hierarchy

  • task_address: Memory address of the object.
  • parent_task_address: Memory address of the task that is the parent of the object.

5,监控并发Request(Monitoring parallel requests)

For requests that are executed in parallel, you will see multiple rows for the same combination of (<session_id>, <request_id>).

SELECT
session_id,
request_id,
task_state,
pending_io_count,
pending_io_byte_count,
pending_io_byte_average,
scheduler_id,
context_switches_count,
task_address,
worker_address,
parent_task_address
FROM sys.dm_os_tasks
ORDER BY session_id, request_id;

或利用 Task Hierarchy来查询

select
tp.session_id,
tp.task_state as ParentTaskState,
tc.task_state as ChildTaskState
from sys.dm_os_tasks tp
inner join sys.dm_os_tasks tc
on tp.task_address=tc.parent_task_address

四,等待资源的Task(waiting)

使用DMV:sys.dm_os_waiting_tasks 查看系统中正在等待资源的Task

  • waiting_task_address: Task that is waiting for this resouce.
  • blocking_task_address: Task that is currently holding this resource
  • resource_description: Description of the resource that is being consumed.  参考sys.dm_os_waiting_tasks (Transact-SQL)

在对阻塞进行故障排除时,查看Block 和 争用的资源:

select wt.waiting_task_address,
wt.session_id,
--Wait and Resource
wt.wait_duration_ms,
wt.wait_type,
wt.resource_address,
wt.resource_description,
wt.blocking_task_address,
wt.blocking_session_id
from sys.dm_os_waiting_tasks wt

五,使用dbcc inputbuffer(spid)获取spid最后一次执行的SQL语句

dbcc inputbuffer(spid)

六,休眠会话(Sleeping Session)

休眠的会话(Sleeping Session)表示当前的会话处于休眠状态,该会话没有运行任何Request。如果一个Session没有运行任何Request,那么该Session为什么不结束,而要保持休眠状态?

休眠会话虽然没有运行任何Request,但是,它和SQL Server的连接并没有断开,出现这种情况的可能原因主要有两个:

  1. Session中存在没有提交的事务;
  2. Session的中所有事务都已经提交,仅仅是没有运行任何Request。

1,查看休眠会话开启的事务

SELECT db_name(dt.database_id) as database_name,
dt.transaction_id,
st.session_id,
dt.database_transaction_begin_time,
CASE dt.database_transaction_type
WHEN 1 THEN 'Read/write transaction'
WHEN 2 THEN 'Read-only transaction'
WHEN 3 THEN 'System transaction'
END database_transaction_type,
CASE dt.database_transaction_state
WHEN 1 THEN 'The transaction has not been initialized.'
WHEN 3 THEN 'The transaction has been initialized but has not generated any log recorst.'
WHEN 4 THEN 'The transaction has generated log recorst.'
WHEN 5 THEN 'The transaction has been prepared.'
WHEN 10 THEN 'The transaction has been committed.'
WHEN 11 THEN 'The transaction has been rolled back.'
WHEN 12 THEN 'The transaction is being committed. In this state the log record is being generated, but it has not been materialized or persisted'
END database_transaction_state,
dt.database_transaction_log_record_count,
dt.database_transaction_log_bytes_used,
dt.database_transaction_log_bytes_reserved
FROM sys.dm_tran_database_transactions dt
INNER JOIN sys.dm_tran_session_transactions st
ON st.transaction_id = dt.transaction_id
inner join sys.dm_exec_sessions s
on st.session_id=s.session_id
where s.status='sleeping'

2,查看休眠会话最后执行的TSQL语句

使用DBCC InputBuffer查看休眠会话最后执行的TSQL语句

dbcc inputbuffer(sleeping_session_id)

3,休眠会话可能产生阻塞

虽然休眠会话占用的资源特别少,但是,如果休眠会话开启的事务不能及时关闭,在某些特定情况下,不仅会阻止事务日志的截断(backup log 能够截断Transaction log,减少日志文件的增长,避免硬盘空间耗尽),甚至会阻塞其他查询。因此,在产品环境中,应当避免出现休眠会话。在开发程序时保证:打开一个连接,执行完相应的查询语句之后,及时提交事务,关闭连接。

附件:引用《How to isolate the current running commands in SQL Server》,该文章描述了如何分离Request执行的查询语句:

SELECT r.[statement_start_offset],
r.[statement_end_offset],
CASE
WHEN r.[statement_start_offset] > 0 THEN
--The start of the active command is not at the beginning of the full command text
CASE r.[statement_end_offset]
WHEN -1 THEN
--The end of the full command is also the end of the active statement
SUBSTRING(st.TEXT, (r.[statement_start_offset]/2) + 1, 2147483647)
ELSE
--The end of the active statement is not at the end of the full command
SUBSTRING(st.TEXT, (r.[statement_start_offset]/2) + 1, (r.[statement_end_offset] - r.[statement_start_offset])/2)
END
ELSE
--1st part of full command is running
CASE r.[statement_end_offset]
WHEN -1 THEN
--The end of the full command is also the end of the active statement
RTRIM(LTRIM(st.[text]))
ELSE
--The end of the active statement is not at the end of the full command
LEFT(st.TEXT, (r.[statement_end_offset]/2) +1)
END
END AS [executing statement],
st.[text] AS [full statement code]
FROM sys.[dm_exec_requests] r
CROSS APPLY sys.[dm_exec_sql_text](r.[sql_handle]) st
WHERE r.session_id > 50
ORDER BY r.[session_id]

参考文档:

Active Request, Sleeping Session

sys.dm_exec_requests (Transact-SQL)

sys.dm_os_tasks (Transact-SQL)

sys.dm_os_waiting_tasks (Transact-SQL)

The SQL Server Wait Type Repository…

SQL Server 查询请求的更多相关文章

  1. SQL Server 磁盘请求超时的833错误原因分析以及解决

    本文出处:http://www.cnblogs.com/wy123/p/6984885.html 最近遇到一个SQL Server服务器响应极度缓慢,并且出现客户端请求报错的情况,在数据库中的erro ...

  2. 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效

    数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...

  3. [转] 利用SET STATISTICS IO和SET STATISTICS TIME 优化SQL Server查询性能

    首先需要说明的是这篇文章的内容并不是如何调节SQL Server查询性能的(有关这方面的内容能写一本书),而是如何在SQL Server查询性能的调节中利用SET STATISTICS IO和SET ...

  4. SQL SERVER 查询性能优化——分析事务与锁(五)

    SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...

  5. SQL Server 查询性能优化 相关文章

    来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Ser ...

  6. 利用SET STATISTICS IO和SET STATISTICS TIME 优化SQL Server查询性能

    首先需要说明的是这篇文章的内容并不是如何调节SQL Server查询性能的(有关这方面的内容能写一本书),而是如何在SQL Server查询性能的调节中利用SET STATISTICS IO和SET ...

  7. 如何找出你性能最差的SQL Server查询

    我经常会被反复问到这样的问题:”我有一个性能很差的SQL Server.我如何找出最差性能的查询?“.因此在今天的文章里会给你一些让你很容易找到问题答案的信息向导. 问SQL Server! SQL ...

  8. 使用WinDbg调试SQL Server查询

    上一篇文章我给你介绍了WinDbg的入门,还有你如何能附加到SQL Server.今天的文章,我们继续往前一步,我会向你展示使用WinDbg调试SQL Server查询需要的步骤.听起来很有意思?我们 ...

  9. sql server 查询分析器消息栏里去掉“(5 行受影响)”

    sql server 查询分析器消息栏里去掉"(5 行受影响)"     在你代码的开始部分加上这个命令: set nocount on   记住在代码结尾的地方再加上: set ...

随机推荐

  1. Oracle Order By 排序 非主键时 紊乱 重复 问题

    Oracle的分页查询是没有进行任何排序操作的,Oracle是顺序的从数据块中读取符合条件的数据返回到客户端. 而Oracle的排序算法不具有稳定性,也就是说,对于排序键值相等的数据,这种算法完成排序 ...

  2. 铁乐学python_Day42_线程池

    铁乐学python_Day42_线程池 concurrent.futures 异步调用模块 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor: ...

  3. php5 Array 数组函数

    函数 描述 array() 创建数组. array_change_key_case() 把数组中所有键更改为小写或大写. array_chunk() 把一个数组分割为新的数组块. array_colu ...

  4. 数据库启动丢失MSVCP120.dll

    在自己第一次安装数据库的时候发生了很多问题,,首当其冲的就是数据库启动时丢失MSVCP120.dll,这里就不配图了(安装好了才想起来写一篇博客). 为什么安装不了? 这是因为系统缺失必要的运行库导致 ...

  5. September 08th 2017 Week 36th Friday

    Death is so terribly final, while life is full of possibilities. 死亡是冰冷可怕的绝境,而或者却充满了无限的可能. It isn't t ...

  6. MySQL复制(一)复制原理探讨

    1 复制概述 1.1.复制解决的问题 数据复制技术有以下一些特点: (1) 数据分布 (2) 负载平衡(load balancing) (3) 备份 (4) 高可用性(high availabilit ...

  7. 20165318 2017-2018-2 《Java程序设计》第六周学习总结

    20165318 2017-2018-2 <Java程序设计>第六周学习总结 教材内容学习总结 第八章 常用实用类 1.String类 String类用来处理字符序列,在java.lang ...

  8. 1192. [HNOI2006]鬼谷子的钱袋【进制】

    Description 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一 ...

  9. 1864. [ZJOI2006]三色二叉树【树形DP】

    Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...

  10. [源码分析]ArrayList

    add public boolean add(E e) { //先确保数组容量 ensureCapacityInternal(size + 1); //直接将值放在size位置 elementData ...