初涉SQL Server性能问题(2/4):列出等待资源的会话

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

初涉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语句。大多数情况下(服务器一致运行稳定,突然卡住了),使用上述步骤就可以解决问题。下一篇文章我们会看下阻塞的会话,还有打开未活动事务的会话 

目录
相关文章
|
8月前
|
SQL 关系型数据库 MySQL
为什么这些 SQL 语句逻辑相同,性能却差异巨大?
我是小假 期待与你的下一次相遇 ~
344 0
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
1275 2
|
12月前
|
SQL 关系型数据库 PostgreSQL
CTE vs 子查询:深入拆解PostgreSQL复杂SQL的隐藏性能差异
本文深入探讨了PostgreSQL中CTE(公共表表达式)与子查询的选择对SQL性能的影响。通过分析两者底层机制,揭示CTE的物化特性及子查询的优化融合优势,并结合多场景案例对比执行效率。最终给出决策指南,帮助开发者根据数据量、引用次数和复杂度选择最优方案,同时提供高级优化技巧和版本演进建议,助力SQL性能调优。
1374 1
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
623 2
|
SQL Oracle 关系型数据库
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
1033 10
|
SQL IDE 数据库连接
IntelliJ IDEA处理大文件SQL:性能优势解析
在数据库开发和管理工作中,执行大型SQL文件是一个常见的任务。传统的数据库管理工具如Navicat在处理大型SQL文件时可能会遇到性能瓶颈。而IntelliJ IDEA,作为一个强大的集成开发环境,提供了一些高级功能,使其在执行大文件SQL时表现出色。本文将探讨IntelliJ IDEA在处理大文件SQL时的性能优势,并与Navicat进行比较。
378 4
|
SQL 数据库 UED
SQL性能提升秘籍:5步优化法与10个实战案例
在数据库管理和应用开发中,SQL查询的性能优化至关重要。高效的SQL查询不仅可以提高应用的响应速度,还能降低服务器负载,提升用户体验。本文将分享SQL优化的五大步骤和十个实战案例,帮助构建高效、稳定的数据库应用。
1634 3
|
SQL 关系型数据库 MySQL
惊呆:where 1=1 可能严重影响性能,差了10多倍,快去排查你的 sql
老架构师尼恩在读者交流群中分享了关于MySQL中“where 1=1”条件的性能影响及其解决方案。该条件在动态SQL中常用,但可能在无真实条件时导致全表扫描,严重影响性能。尼恩建议通过其他条件或SQL子句命中索引,或使用MyBatis的`<where>`标签来避免性能问题。他还提供了详细的执行计划分析和优化建议,帮助大家在面试中展示深厚的技术功底,赢得面试官的青睐。更多内容可参考《尼恩Java面试宝典PDF》。