SQL点滴13—收集SQLServer线程等待信息

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信息是进行数据库优化的依据。    sys.dm_os_wait_stats 这是一个系统视图,里面存储线程所遇到的所有的等待信息,具体的列如下表 列名 数据类型 说明 Wait_type Nvarchar(60) 等待类型名称 waiting_tasks_count Bigint 等待类型的等待数。

要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信息是进行数据库优化的依据。

  

sys.dm_os_wait_stats

这是一个系统视图,里面存储线程所遇到的所有的等待信息,具体的列如下表

列名

数据类型

说明

Wait_type

Nvarchar(60)

等待类型名称

waiting_tasks_count

Bigint

等待类型的等待数。该计数器在每开始一个等待时便会增加。

Wait_time_ms

Bigint

该等待类型的总等待时间。

Max_wait_time_ms

Bigint

该等待类型的最长等待时间。

Signal_wait_time_ms

Bigint

正在等待的线程从收到信号通知到开始运行之间的时差。

要注意的是,这个视图的信息每次关闭SQL Server的时候都会自动清除,下次打开SQL Server的时候又会重新开始统计。

  

新建线程等待信息表

如果想得到连续的信息,在固定时间间隔内收集信息比如一个小时一次,这样就可以分析系统分配的等待时间,识别出繁忙时间段。这里我们将这些信息收集到一个数据表中保存并进行分析。使用下面的语句新建一个表:

 
 
use AdventureWorks

CREATE TABLE dbo.WaitStats

(

dt
DATETIME NOT NULL DEFAULT ( CURRENT_TIMESTAMP ),

wait_type
NVARCHAR ( 60 ) NOT NULL ,

waiting_tasks_count
BIGINT NOT NULL ,

wait_time_ms
BIGINT NOT NULL ,

max_wait_time_ms
BIGINT NOT NULL ,

signal_wait_time_ms
BIGINT NOT NULL

);

CREATE UNIQUE CLUSTERED INDEX idx_dt_type ON dbo.WaitStats(dt, wait_type);

CREATE INDEX idx_type_dt ON dbo.WaitStats(wait_type, dt);

  

新建job填充数据

要收集信息最好是用一个job来定时地执行insert语句填充数据,下面介绍步骤

  1. 点击数据库中的SQL Server Agent,展开,右击jobs文件夹,右击新建。如图1
    img_fa62efefb24ba50816a1117d51fb963a.png

    图1
  2. 在新建job界面,General标签中填写job名称,描述,如图2
    img_32a85937a8c6fb381feaff6983736119.png
    图2
  3. 点击Setps标签,点击新建按钮,在新建step界面内设置Step Name,Type,DataBase,Command等属性,如下图3。这些属性一看就知道是要做什么的,就不一一的解释了。还要说的 是截图是建好的job,如果你自己做的话对话框显示的标题可能不一样。

    img_ebdc2f2d7650ffbb8c11b292a6acb263.png
    图3
    Command属性是设置要执行的SQL语句或存储过程等等,这里设置如下的SQL Script:
     
       
    INSERT INTO Performance.dbo.WaitStats
    (wait_type, waiting_tasks_count, wait_time_ms,
    max_wait_time_ms, signal_wait_time_ms)
    SELECT
    wait_type, waiting_tasks_count, wait_time_ms,
    max_wait_time_ms, signal_wait_time_ms
    FROM sys.dm_os_wait_stats
  4. 点击Shedules标签,设置job的执行计划,这里设置的是每天的每5分钟执行一次如图4
    img_78046cb411e66642ce9d4f0941054a18.png                                                            
    图4

上述步骤包含了新建一个job的主要设置,其他的细节信息没有包含,遇到具体问题再具体分析吧。

收集等待信息数据

过一段时间之后在表WaitStats中就会有一些数据,每隔5分钟就会在这个表中写入一些数据,这些数据会不断的增加。这里为了得到相邻间隔之间线程等待时间的变化就要使用自连接,连接条件是等待类型相同,当前行号等于上一个的行号加上1,然后就可以用上一次等待时间减去这一次的等待时间得到这个变化值,下面使用一个函数来实现这个逻辑:

 
 
IF OBJECT_ID ( ' dbo.IntervalWaits ' , ' IF ' ) IS NOT NULL
DROP FUNCTION dbo.IntervalWaits;
GO
CREATE FUNCTION dbo.IntervalWaits
(
@fromdt AS DATETIME , @todt AS DATETIME )
RETURNS TABLE
AS
RETURN
WITH Waits AS
(
SELECT dt, wait_type, wait_time_ms,
ROW_NUMBER()
OVER (PARTITION BY wait_type
ORDER BY dt) AS rn
FROM dbo.WaitStats
)
SELECT Prv.wait_type, Prv.dt AS start_time,
CAST ((Cur.wait_time_ms - Prv.wait_time_ms)
/ 1000 . AS NUMERIC( 12 , 2 )) AS interval_wait_s
FROM Waits AS Cur
JOIN Waits AS Prv
ON Cur.wait_type = Prv.wait_type
AND Cur.rn = Prv.rn + 1
AND Prv.dt >= @fromdt
AND Prv.dt < DATEADD ( day , 1 , @todt )
GO

这个函数接受两个参数,开始统计时间,结束统计时间,返回等待变化的时间,并按照类型排序。调用这个函数如下:

SELECT wait_type, start_time, interval_wait_s

FROM dbo.IntervalWaits('20110509', '20110510') AS F

ORDER BY SUM(interval_wait_s) OVER(PARTITION BY wait_type) DESC,wait_type,start_time;

但是我们不能每次都去调用这个函数,所以可以吧这个查询放在一个视图里面,外部只需要使用视图来查询数据就可以了:

 
 
IF OBJECT_ID ( ' dbo.IntervalWaitsSample ' , ' V ' ) IS NOT NULL
DROP VIEW dbo.IntervalWaitsSample;
GO
CREATE VIEW dbo.IntervalWaitsSample
AS
SELECT wait_type, start_time, interval_wait_s
FROM dbo.IntervalWaits( ' 20090212 ' , ' 20090215 ' ) AS F;
GO
从视图中查询得到的数据就是我们要得到的数据。但是这些并不明显,先写到这里,下一个随笔我将在EXECL中把这些数据制作成一个直方图或者连线图,横轴是时间,纵轴是等待间隔时间。这样就会更加直观地看到在那些时间SQL Server的线程等待时间最长,也就是最繁忙的时候。

作者:Tyler Ning
出处:http://www.cnblogs.com/tylerdonet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址williamningdong@gmail.com  联系我,非常感谢。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
19天前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
33 8
|
28天前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
3月前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
37 1
|
2月前
|
SQL 数据库
执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)之解决方案
执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)之解决方案
336 0
|
4月前
|
SQL 运维 监控
SQL Server 运维常用sql语句(二)
SQL Server 运维常用sql语句(二)
39 3
|
4月前
|
SQL XML 运维
SQL Server 运维常用sql语句(三)
SQL Server 运维常用sql语句(三)
28 1
|
3月前
|
SQL 存储 监控
SQLServer事务复制延迟优化之并行(多线程)复制
【9月更文挑战第12天】在SQL Server中,事务复制延迟会影响数据同步性。并行复制可通过多线程处理优化这一问题,提高复制效率。主要优化方法包括:配置分发代理参数、优化网络带宽、调整系统资源、优化数据库设计及定期监控维护。合理实施这些措施可提升数据同步的及时性和可靠性。
|
4月前
|
Java 应用服务中间件 Maven
从零到英雄:一步步构建你的首个 JSF 应用程序,揭开 JavaServer Faces 的神秘面纱
【8月更文挑战第31天】JavaServer Faces (JSF) 是一种强大的 Java EE 标准,用于构建企业级 Web 应用。它提供了丰富的组件库和声明式页面描述语言 Facelets,便于开发者快速开发功能完善且易于维护的 Web 应用。本文将指导你从零开始构建一个简单的 JSF 应用,包括环境搭建、依赖配置、Managed Bean 编写及 Facelets 页面设计。
106 0
|
4月前
|
SQL 关系型数据库 MySQL
【超全整理】SQL日期与时间函数大汇总会:MySQL与SQL Server双轨对比教学,助你轻松搞定时间数据处理难题!
【8月更文挑战第31天】本文介绍了在不同SQL数据库系统(如MySQL、SQL Server、Oracle)中常用的日期与时间函数,包括DATE、NOW()、EXTRACT()、DATE_ADD()、TIMESTAMPDIFF()及日期格式化等,并提供了具体示例。通过对比这些函数在各系统中的使用方法,帮助开发者更高效地处理日期时间数据,满足多种应用场景需求。
532 0
|
4月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
466 0