初涉SQL Server性能问题(1/4)里,我们知道了如何快速检查服务器实例上正运行的任务数和IO等待的任务数。这个是轻量级的脚本,不会给服务器造成任何压力,即使服务器在高负荷下,也可以正常获得结果。

问题检测的第2步是获取在进行任何资源等待的会话。下面的脚本会帮助我们获得这些信息。这个查询需要预建立一个函数,如果会话是由SQL Server代理启动的话,会显示具体的作业名。

  1. /*****************************************************************************************
  2. PREREQUISITE FUNCTION
  3. ******************************************************************************************/
  4. USE MASTER
  5. GO
  6. CREATE FUNCTION ConvertStringToBinary ( @hexstring VARCHAR(100)
  7. ) RETURNS BINARY(34) AS
  8. BEGIN
  9.  
  10. RETURN(SELECT CAST('' AS XML).value('xs:hexBinary( substring(sql:variable("@hexstring"), sql:column("t.pos")) )', 'varbinary(max)')
  11. FROM (SELECT CASE SUBSTRING(@hexstring, 1, 2) WHEN '0x' THEN 3 ELSE 0 END) AS t(pos))
  12. END
  13. /***************************************************************************************
  14. STEP 2: List the session which are currently waiting for resource
  15. ****************************************************************************************/
  16. SELECT node.parent_node_id AS Node_id,
  17. es.HOST_NAME,
  18. es.Login_name,
  19. CASE WHEN es.program_name LIKE '%SQLAgent - TSQL JobStep%' THEN
  20. (
  21. SELECT 'SQL AGENT JOB: '+name FROM msdb..sysjobs WHERE job_id=
  22. MASTER.DBO.ConvertStringToBinary (LTRIM(RTRIM((SUBSTRING(es.program_name,CHARINDEX('(job',es.program_name,0)+4,35)))))
  23. )
  24. ELSE es.program_name END AS [Program Name] ,
  25. DB_NAME(er.database_id) AS DatabaseName,
  26. er.session_id,
  27. wt.blocking_session_id,
  28. wt.wait_duration_ms,
  29. wt.wait_type,
  30. wt.NoThread ,
  31. er.command,
  32. er.status,
  33. er.wait_resource,
  34. er.open_transaction_count,
  35. er.cpu_time,
  36. er.total_elapsed_time AS ElapsedTime_ms,
  37. er.percent_complete ,
  38. er.reads,
  39. er.writes,
  40. er.logical_reads,
  41. wlgrp.name AS ResoursePool ,
  42. SUBSTRING (sqltxt.TEXT,(er.statement_start_offset/2) + 1,
  43. ((CASE WHEN er.statement_end_offset = -1
  44. THEN LEN(CONVERT(NVARCHAR(MAX), sqltxt.TEXT)) * 2
  45. ELSE er.statement_end_offset
  46. END - er.statement_start_offset)/2) + 1) AS [Individual Query],
  47. sqltxt.TEXT AS [Batch Query]
  48. FROM (SELECT session_id, SUM(wait_duration_ms) AS
  49. wait_duration_ms,wait_type,blocking_session_id,COUNT(*) AS NoThread
  50. FROM SYS.DM_OS_WAITING_TASKS GROUP BY session_id, wait_type,blocking_session_id) wt
  51. INNER JOIN SYS.DM_EXEC_REQUESTS er ON wt.session_id=er.session_id INNER JOIN SYS.DM_EXEC_SESSIONS es ON es.session_id= er.session_id
  52. INNER JOIN SYS.DM_RESOURCE_GOVERNOR_WORKLOAD_GROUPS wlgrp ON wlgrp.group_id=er.group_id
  53. INNER JOIN (SELECT os.parent_node_id ,task_address FROM SYS.DM_OS_SCHEDULERS OS INNER JOIN
  54. SYS.DM_OS_WORKERS OSW ON OS.scheduler_address=OSW.scheduler_address
  55. WHERE os.status='VISIBLE ONLINE' GROUP BY os.parent_node_id ,task_address ) node
  56. ON node.task_address=er.task_address
  57. CROSS APPLY SYS.DM_EXEC_SQL_TEXT(er.sql_handle) AS sqltxt
  58. WHERE sql_handle IS NOT NULL AND wt.wait_type NOT IN ('WAITFOR','BROKER_RECEIVE_WAITFOR')
  59. GO

输出结果的每列说明介绍如下:

  • Node_id  NUMA节点ID。可以被调度者查询的节点映射。
  • HOST_NAME 建立连接的计算机名。
  • Login_name 连接到数据库服务器的会话用户名。
  • Program Name 使用会话的对应程序名。在连接字符串里可以设置程序名。如果会话是SQL Server代理的一部分,则显示作业名。
  • DatabaseName 会话的当前数据库名。
  • session_id 会话ID。
  • blocking_session_id 阻塞语句的会话ID。
  • wait_duration_ms 等待时间,单位为毫秒。这个时间不包括信号等待时间(signal wait time )。
  • wait_type 等待类型名称,例如:SLEEP_TASK,CXPACKET等。
  • NoThread 当前会话的线程数,如果当前会话是并行执行(parallel execution)的话。
  • command 标识当前类型的命令,即T-SQL语句,例如Select,insert,update,delete等。
  • status 请求状态:Background,Running,Runnable,Sleeping 和 Suspended。
  • wait_resource 请求当前等待的资源。
  • open_transaction_count 当前会话打开的事务数。
  • cpu_time 请求使用的CPU时间,单位毫秒。
  • ElapsedTime_ms 自请求到达后,占用的CPU时间,单位毫秒。
  • percent_complete 指定操作的工作完成进度,例如备份、还原、回滚等。
  • reads 请求执行的读数。
  • writes 请求执行的写数。
  • logical_reads 请求执行的逻辑读数。
  • ResoursePool 资源管理池名称。
  • Individual Query 在会话里运行的批处理SQL语句。
  • Batch Query 在会话里运行的批处理(存储过程/一系列的语句)。

上述查询多次执行后,输出结果有很长wait_duration_ms的会话,这个会话不被其他会话阻塞,且一直在输出结果里。我们就要看看这个会话的程序名,主机名,登录用户名,还有对应的执行语句,具体进行什么操作造成的。根据这些信息,我们可以选择性的去终止这个会话,然后分析下具体的执行语句。如果会话是被阻塞的,我们要用另外的语句来找出阻塞的会话。

第3步,列出服务器上正运行的会话清单。

  1. /***************************************************************************************
  2. STEP 3: List the session which are currently waiting/running
  3. ****************************************************************************************/
  4. SELECT node.parent_node_id AS Node_id,
  5. es.HOST_NAME,
  6. es.login_name,
  7. CASE WHEN es.program_name LIKE '%SQLAgent - TSQL JobStep%' THEN
  8. (SELECT 'SQL AGENT JOB: '+name FROM msdb..sysjobs WHERE job_id=DBO.ConvertStringToBinary (LTRIM(RTRIM((SUBSTRING(es.program_name,CHARINDEX('(job',es.program_name,0)+4,35)))))
  9. )ELSE es.program_name END AS program_name ,
  10. DB_NAME(er.database_id) AS DatabaseName,
  11. er.session_id,
  12. wt.blocking_session_id,
  13. wt.wait_duration_ms,
  14. wt.wait_type,
  15. wt.NoThread ,
  16. er.command,
  17. er.status,
  18. er.wait_resource,
  19. er.open_transaction_count,
  20. er.cpu_time,
  21. er.total_elapsed_time AS ElapsedTime_ms,
  22. er.percent_complete ,
  23. er.reads,er.writes,er.logical_reads,
  24. wlgrp.name AS ResoursePool ,
  25. SUBSTRING (sqltxt.TEXT,(er.statement_start_offset/2) + 1,
  26. ((CASE WHEN er.statement_end_offset = -1
  27. THEN LEN(CONVERT(NVARCHAR(MAX), sqltxt.TEXT)) * 2
  28. ELSE er.statement_end_offset
  29. END - er.statement_start_offset)/2) + 1) AS [Individual Query],
  30. sqltxt.TEXT AS [Batch Query]
  31. FROM
  32. SYS.DM_EXEC_REQUESTS er INNER JOIN SYS.DM_EXEC_SESSIONS es ON es.session_id= er.session_id
  33. INNER JOIN SYS.DM_RESOURCE_GOVERNOR_WORKLOAD_GROUPS wlgrp ON wlgrp.group_id=er.group_id
  34. INNER JOIN (SELECT os.parent_node_id ,task_address FROM SYS.DM_OS_SCHEDULERS OS
  35. INNER JOIN SYS.DM_OS_WORKERS OSW ON OS.scheduler_address=OSW.scheduler_address
  36. WHERE os.status='VISIBLE ONLINE' GROUP BY os.parent_node_id ,task_address ) node ON node.task_address=er.task_address
  37. LEFT JOIN
  38. (SELECT session_id, SUM(wait_duration_ms) AS
  39. wait_duration_ms,wait_type,blocking_session_id,COUNT(*) AS NoThread
  40. FROM SYS.DM_OS_WAITING_TASKS GROUP BY session_id, wait_type,blocking_session_id) wt
  41. ON wt.session_id=er.session_id
  42. CROSS apply SYS.DM_EXEC_SQL_TEXT(er.sql_handle) AS sqltxt
  43. WHERE sql_handle IS NOT NULL AND ISNULL(wt.wait_type ,'') NOT IN
  44. ('WAITFOR','BROKER_RECEIVE_WAITFOR')
  45. ORDER BY er.total_elapsed_time DESC
  46.  
  47. GO

这里的输出列和第2步完全相同,我会分析total_elapsed_time占用时间较长的会话,酌情考虑是否终止这些会话,并分析下对应的执行SQL语句。大多数情况下(服务器一致运行稳定,突然卡住了),使用上述步骤就可以解决问题。下一篇文章我们会看下阻塞的会话,还有打开未活动事务的会话

参考文章:

http://www.sqlservercentral.com/blogs/practicalsqldba/2012/09/21/sql-server-part-2-approaching-database-server-performance-issues/

初涉SQL Server性能问题(2/4):列出等待资源的会话的更多相关文章

  1. 初涉SQL Server性能问题(4/4):列出最耗资源的会话

    在上3篇文章里,我们讨论了列出反映服务器当前状态的不同查询. 初涉SQL Server性能问题(1/4):服务器概况 初涉SQL Server性能问题(2/4):列出等待资源的会话 初涉SQL Ser ...

  2. 初涉SQL Server性能问题(3/4):列出阻塞的会话

    在 初涉SQL Server性能问题(2/4)里,我们讨论了列出等待资源或正运行的会话脚本.这篇文章我们会看看如何列出包含具体信息的话阻塞会话清单. /************************ ...

  3. 初涉SQL Server性能问题(1/4):服务器概况

    当你作为DBA时,很多人会向你抱怨:“这个程序数据加载和蜗牛一样,你看看是不是服务器出问题了?”造成这个问题的原因有很多.可能是程序应用服务器问题,网络问题,程序实现方式问题,数据库服务器负荷过重.不 ...

  4. SQL Server 性能优化之——系统化方法提高性能

    SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...

  5. SQL Server 性能优化详解

    故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...

  6. SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈【转】

    转载自:http://blog.csdn.net/dba_huangzj/article/details/7607844#comments 通过DMV查看当时SQL SERVER所有任务的状态(sle ...

  7. SQL Server 性能调优培训引言

    原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...

  8. SQL Server 性能优化(一)——简介

    原文:SQL Server 性能优化(一)--简介 一.性能优化的理由: 听起来有点多余,但是还是详细说一下: 1.节省成本:这里的成本不一定是钱,但是基本上可以变相认为是节省钱.性能上去了,本来要投 ...

  9. SQL Server性能优化与管理的艺术 附件下载地址

    首先感谢读者们对鄙人的支持,购买了<SQL Server性能优化与管理的艺术>,由于之前出版社的一些疏忽,附件没有上传成功,再次本人深表歉意. 请需要下载附件的读者从下面链接下载,谢谢: ...

随机推荐

  1. 针对远程Git代码库使用SSH公匙

    → 运行Git Bash→ 创建SSH公匙和私匙ssh-keygen -t rsa→ 输入SSH公匙存放文件,选择使用默认的,按Enter→ 如果已经存在,提示是否重写,输入n,按Enter→ 打开C ...

  2. Linux--Ubuntu12.04下安装JDK

    前言 在Ubuntu中安装JDK的方法非常的多,网上现在介绍的很多方法,都不是很清楚,对于初学者,很多都不太明白如何安装.本篇博客就Ubuntu下安装JDK进行详细的讲解,这里使用的Ubuntu版本为 ...

  3. xcode 编译器在各个arch下面默认宏

    $ clang -dM -E -arch armv7 -x c /dev/null #define OBJC_NEW_PROPERTIES 1 #define __APCS_32__ 1 #defin ...

  4. 使用cxf开发webservice应用时抛出异常

    在使用cxf开发webservice应用时,报出了类似下面的错误 JAXB: [javax.xml.bind.UnmarshalException: unexpected element (uri:& ...

  5. [转] Linux学习之CentOS(三十六)--FTP服务原理及vsfptd的安装、配置

    本篇随笔将讲解FTP服务的原理以及vsfptd这个最常用的FTP服务程序的安装与配置... 一.FTP服务原理 FTP(File Transfer Protocol)是一个非常古老并且应用十分广泛的文 ...

  6. 正则指引-量词demo

    class Program { static void Main(string[] args) { string str = "1\"3"; var re1 = Rege ...

  7. js实现hash

    由于项目中用到了hash,自己实现了一个. Hash = function () { } Hash.prototype = { constructor: Hash, add: function (k, ...

  8. Android学习之ProgressBar

    ProgressBar用于向用户显示某个耗时操作完成的百分比,避免长时间执行某个耗时操作时让用户感觉程序失去了响应,从而提高用户界面的友好性. 请看下面的界面布局: <LinearLayout ...

  9. 所有文章都迁移到我自己的博客了:http://blog.neazor.com

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  10. iOS:缓存与Operation优先级问题

    这篇博客来源于今年的一个面试题,当我们使用SDWebImgae框架中的sd_setImageWithURL: placeholderImage:方法在tableView或者collectionView ...