sql server怎样用扩展事件捕获带变量值的慢sql

sqlserver查询当前执行的sql时,经常看到带变量如@PO,@P1的sql,没有具体的值,有的sql甚至有几十个变量,优化的时候需要一个个手动代入,很是不方便。

用扩展事件可以捕获带变量值的慢sql。

当cpu高的时候,可以创建并启动个扩展事件来捕获慢sql。

已验证在always on集群从库上创建扩展事件,不影响主从数据同步。

本文以捕获超过一秒的慢sql为例。

一 创建扩展事件

复制代码
IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name = 'slow_query')  

    DROP EVENT SESSION slow_query ON SERVER   

GO  

--  创建事件会话  

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,sqlserver.client_hostname,sqlserver.client_app_name)

    WHERE  [duration]>=1000000                    -- 消耗秒数超 1 秒      

    ),

ADD EVENT sqlserver.sql_batch_completed(

    ACTION(sqlos.task_time,sqlserver.database_name,sqlserver.nt_username,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username,sqlserver.client_hostname,sqlserver.client_app_name)

    WHERE   [duration]>=1000000                    -- 消耗秒数超 1 秒  

      )

ADD TARGET package0.event_file(SET filename=N'D:\test\slow_query.xel',max_file_size=(1000))    --路径、文件MB, 自行修改

WITH (STARTUP_STATE=ON)

GO

--  启用(停止)事件会话(START / STOP)  

ALTER EVENT SESSION slow_query ON SERVER STATE=START  

GO

二 模拟慢sql-执行一个大于1秒的慢sql

select * from test2 where id>15000000

三 查看监测到的数据

有两种方式可以查询。

用SSMS可以看到每条慢sql的详细记录,但如果sql较多,可以用sql筛选想查的数据,比较灵活。

3.1 用SSMS查

--备注:扩展事件创建之后执行的慢sql也能捕获到。

3.2 用sql查

查看下生成的xel文件,手动改下下面的xel文件名

3.2.1 查看具体一个个慢sql记录

复制代码
with d as (

SELECT CONVERT(XML,event_data) AS data

from sys.Fn_xe_file_target_read_file(N'D:\test\slow_query_0_133763843782130000.xel',NULL,NULL,NULL)

)

select

dateadd(hour,8,data.value('(/event/@timestamp)[1]','datetime')) as record_time, --获取最上方标题行的内容

data.value('(/event/data[@name="cpu_time"]/value)[1]','int')/1000 as 'cpu_time(ms)',--获得 event=>data name=cpu_time 的 value

data.value('(/event/data[@name="duration"]/value)[1]','int')/1000 as 'exec_time(ms)',--获得 event=>data name=duration 的 value

--data.value('(/event/data[@name="batch_text"]/value)[1]','nvarchar(max)') as 'batch_text',--获得 event=>data name=batch_text 的 text

data.value('(/event/action[@name="sql_text"]/value)[1]','nvarchar(4000)') as 'current_param_sql',--获得 event=>action name=sql_text 的 value
data.value('(/event/data[@name="statement"]/value)[1]','nvarchar(4000)') as 'current_value_sql',--获得 event=>data name=statement的 value

--data.value('(/event/action[@name="task_time"]/value)[1]','int')/1000 as 'task_time(ms)',--获得 event=>action name=task_time 的 value

data.value('(/event/action[@name="database_name"]/value)[1]','nvarchar(400)') as 'database_name',--获得 event=>action name=database_name 的 value

data.value('(/event/action[@name="transaction_id"]/value)[1]','nvarchar(400)') as 'transaction_id',--获得 event=>action name=transaction_id 的 value

data.value('(/event/action[@name="username"]/value)[1]','nvarchar(400)') as 'username',--获得 event=>action name=username 的 value

data.value('(/event/action[@name="nt_username"]/value)[1]','nvarchar(400)') as 'nt_username',--获得 event=>action name=nt_username 的 value

data.value('(/event/action[@name="client_hostname"]/value)[1]','nvarchar(400)') as 'client_hostname',--获得 event=>action name=client_hostname 的 value

data.value('(/event/action[@name="client_app_name"]/value)[1]','nvarchar(400)') as 'client_app_name',--获得 event=>action name=client_app_name 的 value

data.value('(/event/@name)[1]','nvarchar(128)') as operation_name, --获取最上方标题行的内容

data.value('(/event/data[@name="physical_reads"]/value)[1]','int') as 'physical_reads',--获得 event=>data name=physical_reads 的 value

data.value('(/event/data[@name="logical_reads"]/value)[1]','int') as 'logical_reads',--获得 event=>data name=logical_reads 的 value

data.value('(/event/data[@name="writes"]/value)[1]','int') as 'writes',--获得 event=>data name=writes 的 value

data.value('(/event/data[@name="row_count"]/value)[1]','int') as 'row_count',--获得 event=>data name=row_count 的 value

data.value('(/event/data[@name="result"]/value)[1]','int') as 'result_flag',--获得 event=>data name=result 的 value

data.value('(/event/data[@name="result"]/text)[1]','nvarchar(128)') as 'result_desc'--获得 event=>data name=result 的 text

from d

order by "cpu_time(ms)" desc

3.2.3 查看汇总版的慢sql(某个sql执行次数,平均执行时长,总体执行时长等信息)

复制代码
with d as (
 
SELECT CONVERT(XML,event_data) AS data
 
from sys.Fn_xe_file_target_read_file(N'D:\test\slow_query_0_133764079441250000.xel',NULL,NULL,NULL)
 
),
 e as
(
 
select 
 
dateadd(hour,8,data.value('(/event/@timestamp)[1]','datetime')) as record_time, --获取最上方标题行的内容
 --
data.value('(/event/data[@name="cpu_time"]/value)[1]','int')/1000 as 'cpu_time_ms',--获得 event=>data name=cpu_time 的 value
 
data.value('(/event/data[@name="duration"]/value)[1]','int')/1000 as 'exec_time_ms',--获得 event=>data name=duration 的 value
 
--data.value('(/event/data[@name="batch_text"]/value)[1]','nvarchar(max)') as 'batch_text',--获得 event=>data name=batch_text 的 text
 
data.value('(/event/action[@name="sql_text"]/value)[1]','nvarchar(4000)') as 'current_param_sql',--获得 event=>action name=sql_text 的 value
data.value('(/event/data[@name="statement"]/value)[1]','nvarchar(4000)') as 'current_value_sql',--获得 event=>data name=sql_text 的 value
 
 
--data.value('(/event/action[@name="task_time"]/value)[1]','int')/1000 as 'task_time(ms)',--获得 event=>action name=task_time 的 value
 
data.value('(/event/action[@name="database_name"]/value)[1]','nvarchar(400)') as 'database_name',--获得 event=>action name=database_name 的 value
 
data.value('(/event/action[@name="transaction_id"]/value)[1]','nvarchar(400)') as 'transaction_id',--获得 event=>action name=transaction_id 的 value
 
data.value('(/event/action[@name="username"]/value)[1]','nvarchar(400)') as 'username',--获得 event=>action name=username 的 value
 
data.value('(/event/action[@name="nt_username"]/value)[1]','nvarchar(400)') as 'nt_username',--获得 event=>action name=nt_username 的 value
 
data.value('(/event/action[@name="client_hostname"]/value)[1]','nvarchar(400)') as 'client_hostname',--获得 event=>action name=client_hostname 的 value
 
data.value('(/event/action[@name="client_app_name"]/value)[1]','nvarchar(400)') as 'client_app_name',--获得 event=>action name=client_app_name 的 value
 
data.value('(/event/@name)[1]','nvarchar(128)') as operation_name, --获取最上方标题行的内容
 
data.value('(/event/data[@name="physical_reads"]/value)[1]','int') as 'physical_reads',--获得 event=>data name=physical_reads 的 value
 
data.value('(/event/data[@name="logical_reads"]/value)[1]','int') as 'logical_reads',--获得 event=>data name=logical_reads 的 value
 
data.value('(/event/data[@name="writes"]/value)[1]','int') as 'writes',--获得 event=>data name=writes 的 value
 
data.value('(/event/data[@name="row_count"]/value)[1]','int') as 'row_count',--获得 event=>data name=row_count 的 value
 
data.value('(/event/data[@name="result"]/value)[1]','int') as 'result_flag',--获得 event=>data name=result 的 value
 
data.value('(/event/data[@name="result"]/text)[1]','nvarchar(128)') as 'result_desc'--获得 event=>data name=result 的 text

from d 
)
select database_name,current_param_sql,max(current_value_sql) as current_value_sql,count(*) as cnt,sum(cpu_time_ms) as sum_cpu_time_ms,sum(exec_time_ms) as sum_exec_time_ms,avg(cpu_time_ms) as avg_cpu_time_ms,avg(exec_time_ms) as avg_exec_time_ms,max(username) as username,max(client_hostname) as client_hostname,max(client_app_name) as client_app_name,max(row_count) as max_row_count
from e 
group by current_param_sql,database_name
order by sum_cpu_time_ms desc

--本篇文章参考了

【监控笔记】【2.3】扩展事件------慢查询SQL(执行超过3S的SQL) - 郭大侠1 - 博客园

并做了些许改动。

相关推荐
冉冰学姐2 小时前
SSM公办小学网络报名系统f3d3p(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·ssm 框架·公办小学网络报名系统·教育信息化
叡鳍2 小时前
hive---HQL查询
数据库
vortex53 小时前
谷歌黑客语法挖掘 SQL 注入漏洞
android·数据库·sql
九河云3 小时前
软件开发平台 DevCloud
运维·服务器·数据库·科技·华为云
wind_one14 小时前
7.基础--SQL--DDL-数据类型及案例
数据库·sql
l1t5 小时前
利用DeepSeek改写SQLite版本的二进制位数独求解SQL
数据库·人工智能·sql·sqlite
QT 小鲜肉5 小时前
【QT/C++】Qt定时器QTimer类的实现方法详解(超详细)
开发语言·数据库·c++·笔记·qt·学习
研究司马懿5 小时前
【ETCD】ETCD常用命令
网络·数据库·云原生·oracle·自动化·运维开发·etcd
刘一说7 小时前
深入理解 Spring Boot 中的数据库迁移:Flyway 与 Liquibase 实战指南
数据库·spring boot·oracle
August_._7 小时前
【MySQL】SQL语法详细总结
java·数据库·后端·sql·mysql·oracle