SQL Server 通过扩展事件捕获慢SQL

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: SQL Server 通过扩展事件捕获慢SQL

背景

在业务使用中,经常会遇应用响应缓慢的影响,通过第一时间需要排查的问题就是数据库性能问题,这时我们就需要查找哪些SQL需要优化?而SQL Server 并没有像MySQL直接记录慢SQL的功能,本文介绍通过使用扩展事件来捕获慢SQL。

目的

通过使用SQL Server扩展事件技术,来捕获数据库使用中产生的慢SQL,为性能优化提供便利。

SQL Server扩展事件

扩展事件体系结构使用户能够收集尽可能多的或少的数据,以排查或识别SQL Server实例中的性能问题。 扩展事件高度可配置、轻型且可很好地缩放。

捕获慢SQL操作流程

1、检查已经有的扩展事件

select*from sys.server_event_sessions;

2、删除扩展事件

if exists (select*from sys.server_event_sessionswhere name ='slow_query')drop event session slow_query on server

3、创建扩展事件

create event session [slow_query]on server
add event sqlserver.rpc_completed(action(sqlos.task_time,sqlserver.database_name,sqlserver.nt_username,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)where  sqlserver.database_name='db01'-- and sqlserver.username = 'username'and([duration]>=3000000or[row_count]>=10000or[physical_reads]>=12800or[logical_reads]>=128000or[cpu_time]>=500000or[writes]>=12800)), add event sqlserver.sql_batch_completed( action(sqlos.task_time,sqlserver.database_name,sqlserver.nt_username,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)where  sqlserver.database_name='db01'-- and sqlserver.username = 'username'and([duration]>=3000000or[row_count]>=10000or[physical_reads]>=12800or[logical_reads]>=128000or[cpu_time]>=500000or[writes]>=12800))  add target package0.event_file(set filename=N'D:\MSSQL\EventLog\slow_query.xel',max_file_size=(10))  with(startup_state=on)

说明:

  • create event:创建扩展事件语句
  • slow_query:扩展事件名称
  • add event:添加事件
  • sqlserver.rpc_completed:包名(sqlserver SQL Server 相关对象):事件名称(rpc_completed 远程过程调用完成时触发
  • add action 添加全局字段的输出
  • where : 条件筛选
  • sqlserver.database_name 筛选指定的数据库名称
  • sqlserver.username 筛选指定的账号名称
  • [duration]>=3000000 筛选执行时间大于3秒操作
  • [row_count]>=10000 筛选返回行数大于10000操作
  • [physical_reads] >= 12800 筛选物理读取大于100MB操作 128 * 100 * 8K
  • [logical_reads] >= 12800 筛选逻辑读取大于1GB操作 128 * 1000 * 8K
  • [cpu_time] >= 500000  筛选cpu执行时间大于0.5秒操作
  • [writes] >= 12800 筛选写入大于100MB操作 128 * 100 * 8K
  • add target:添加指定的文件输出


列出所有的action

select dxp.name,dxo.name,dxo.description,dxp.descriptionfrom sys. dm_xe_objects dxo inner join sys.dm_xe_packages dxp 
on dxo.package_guid= dxp.guidwhere dxo.object_type='action';

4、开启扩展事件

alter event session slow_query on server state=start;

验证效果

Case 1:执行12秒的SQL


Case 2:返回行数10000行


将XML转换表格输出

1、通过命令查找XML路径

select s.nameas xe_session_name,    cast(st.target_dataas xml)as target_data
from sys.dm_xe_sessions s 
inner join sys.dm_xe_session_targets st 
on s.address=st.event_session_addresswhere s.name='slow_query';

结果展示 1

结果展示 2


2、通过命令分析XML结构

select cast(event_data as xml) event_data,*from sys.fn_xe_file_target_read_file(N'D:\MSSQL\EventLog\slow_query_0_133166686786020000.xel',NULL,NULL,NULL)where OBJECT_NAME='sql_batch_completed';

结果展示 1


XML结构展示 2


3、根据XML转换表格类型

sql_batch_completed 类型转换

SELECT DATEADD(hour,8,[XML Data].value('(/event[@name=''sql_batch_completed'']/@timestamp)[1]','DATETIME'))AS[TimeStamp],[XML Data].value('(/event/action[@name=''database_name'']/value)[1]','SYSNAME')AS[Database Name],[XML Data].value('(/event/action[@name=''sql_text'']/value)[1]','SYSNAME')AS[SQL_Text],[XML Data].value('(/event/action[@name=''username'']/value)[1]','SYSNAME')AS username,[XML Data].value('(/event/action[@name=''task_time'']/value)[1]','BIGINT')AS task_time,[XML Data].value('(/event/data[@name=''duration'']/value)[1]','BIGINT')AS[Duration (us)],[XML Data].value('(/event/data[@name=''cpu_time'']/value)[1]','BIGINT')AS[cpu_time],[XML Data].value('(/event/data[@name=''physical_reads'']/value)[1]','BIGINT')AS physical_reads,[XML Data].value('(/event/data[@name=''logical_reads'']/value)[1]','BIGINT')AS logical_reads,[XML Data].value('(/event/data[@name=''writes'']/value)[1]','BIGINT')AS writes,[XML Data].value('(/event/data[@name=''row_count'']/value)[1]','BIGINT')AS row_count,[XML Data].value('(/event/data[@name=''batch_text'']/value)[1]','SYSNAME')AS batch_text
FROM(SELECT CONVERT(XML, event_data)AS[XML Data]FROM  sys.fn_xe_file_target_read_file(N'D:\MSSQL\EventLog\slow_query_0_133166686786020000.xel',NULL,NULL,NULL)where OBJECT_NAME='sql_batch_completed')AS v;


rpc_completed 类型转换

SELECT DATEADD(hour,8,[XML Data].value('(/event[@name=''rpc_completed'']/@timestamp)[1]','DATETIME'))AS[TimeStamp],[XML Data].value('(/event/action[@name=''database_name'']/value)[1]','SYSNAME')AS[Database Name],[XML Data].value('(/event/action[@name=''sql_text'']/value)[1]','SYSNAME')AS[SQL_Text],[XML Data].value('(/event/action[@name=''username'']/value)[1]','SYSNAME')AS username,[XML Data].value('(/event/action[@name=''task_time'']/value)[1]','BIGINT')AS task_time,[XML Data].value('(/event/data[@name=''duration'']/value)[1]','BIGINT')AS[Duration (us)],[XML Data].value('(/event/data[@name=''cpu_time'']/value)[1]','BIGINT')AS[cpu_time],[XML Data].value('(/event/data[@name=''physical_reads'']/value)[1]','BIGINT')AS physical_reads,[XML Data].value('(/event/data[@name=''logical_reads'']/value)[1]','BIGINT')AS logical_reads,[XML Data].value('(/event/data[@name=''writes'']/value)[1]','BIGINT')AS writes,[XML Data].value('(/event/data[@name=''row_count'']/value)[1]','BIGINT')AS row_count
FROM(SELECT CONVERT(XML, event_data)AS[XML Data]FROM  sys.fn_xe_file_target_read_file(N'D:\MSSQL\EventLog\slow_query_0_133166686786020000.xel',NULL,NULL,NULL)where OBJECT_NAME='rpc_completed')AS v;

结果查询

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
2月前
|
SQL 开发框架 .NET
突破T-SQL限制:利用CLR集成扩展RDS SQL Server的功能边界
CLR集成为SQL Server提供了强大的扩展能力,突破了T-SQL的限制,极大地拓展了SQL 的应用场景,如:复杂字符串处理、高性能计算、图像处理、机器学习集成、自定义加密解密等,使开发人员能够利用 .NET Framework的丰富功能来处理复杂的数据库任务。
|
2月前
|
SQL
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
46 1
|
3月前
|
SQL 数据库
执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)之解决方案
执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)之解决方案
540 0
|
4月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
4月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL 运维 监控
SQL Server 运维常用sql语句(二)
SQL Server 运维常用sql语句(二)
49 3
|
5月前
|
SQL XML 运维
SQL Server 运维常用sql语句(三)
SQL Server 运维常用sql语句(三)
42 1
|
5月前
|
SQL 关系型数据库 MySQL
SQL数据库和 SQLserver数据库
【8月更文挑战第19天】SQL数据库和 SQLserver数据库
74 2
|
5月前
|
Java 应用服务中间件 Maven
从零到英雄:一步步构建你的首个 JSF 应用程序,揭开 JavaServer Faces 的神秘面纱
【8月更文挑战第31天】JavaServer Faces (JSF) 是一种强大的 Java EE 标准,用于构建企业级 Web 应用。它提供了丰富的组件库和声明式页面描述语言 Facelets,便于开发者快速开发功能完善且易于维护的 Web 应用。本文将指导你从零开始构建一个简单的 JSF 应用,包括环境搭建、依赖配置、Managed Bean 编写及 Facelets 页面设计。
115 0
|
5月前
|
SQL 关系型数据库 MySQL
【超全整理】SQL日期与时间函数大汇总会:MySQL与SQL Server双轨对比教学,助你轻松搞定时间数据处理难题!
【8月更文挑战第31天】本文介绍了在不同SQL数据库系统(如MySQL、SQL Server、Oracle)中常用的日期与时间函数,包括DATE、NOW()、EXTRACT()、DATE_ADD()、TIMESTAMPDIFF()及日期格式化等,并提供了具体示例。通过对比这些函数在各系统中的使用方法,帮助开发者更高效地处理日期时间数据,满足多种应用场景需求。
639 0