【监控笔记】【2.3】扩展事件——慢查询SQL(执行超过3S的SQL)

 


--sql server 2008及以上才支持,2012及以上才支持GUI界面

msdn 扩展事件:点击打开链接

 【1】T-SQL实现

【1.1】T-SQL构建慢查询扩展日志

基于 rpc_completed(远程过程调用已完成时发生) 事件与 sql_batch_completed(Transact-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)
    WHERE  [duration]>=3000000                    -- 消耗秒数超 3 秒
    AND [sqlserver].[database_name]=N'asdegame'    -- 数据库名, 自行修改
    --and sqlserver.username=N'xxxx'                -- 数据库用户名, 自行修改
   
    ),
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   [duration]>=3000000                    -- 消耗秒数超 3 秒
    AND [sqlserver].[database_name]=N'asdegame'   -- 数据库名, 自行修改
    --and sqlserver.username=N'xxxx'                -- 数据库用户名, 自行修改
  
    )
ADD TARGET package0.event_file(SET filename=N'E:\dba_tools\eventlog\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  
复制代码

【1.2】使用sql 查询扩展事件文件

SELECT CONVERT(XML,event_data) AS data
sys.Fn_xe_file_target_read_file(N'd:\xe_sessions\servername_ev_block_session.xel',NULL,NULL,NULL)

【1.3】转成表格查阅

复制代码
with d as (
SELECT CONVERT(XML,event_data) AS data
from sys.Fn_xe_file_target_read_file(N'E:\dba_tools\eventlog\slow_query_0_132422809173040000.xel',NULL,NULL,NULL)
)
select
dateadd(hour,8,data.value('(/event/@timestamp)[1]','datetime')) as record_time, --获取最上方标题行的内容
data.value('(/event/@name)[1]','nvarchar(128)') as operation_name, --获取最上方标题行的内容
--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="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
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_sql',--获得 event=>action 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=transaction_id 的 value
data.value('(/event/action[@name="nt_username"]/value)[1]','nvarchar(400)') as 'nt_username'--获得 event=>action name=transaction_id 的 value
from d
复制代码

 

  

 

 

【2】GUI实现

  

 

 

基于 sql_statement_completed(Transact-SQL 语句已完成时发生)

和 query_post_execution_showplan (在执行 SQL 语句后发生。此事件返回实际查询计划的 XML 表示形式。使用此事件可能带来严重的性能开销,所以只有在短时间内解决或监视特定问题时才应使用此事件。)

  (1)新建会话,把sql_statement_completed 和 query_post_execution_showplan 事件给选上

  

 

  (2)谓词 筛选出持续时间大于3s的,并排除系统数据库,两个事件都这么设置

    

  (3)实时监控,查看结果

    

  (4)再做修改,加全局字段与事件字段。而query_post_execution_showplan事件加了username全局字段和databaseName

    

 

 

   (5)查看加了字段之后的结果

    

 

 

 

相关参考文章:

  概念与介绍~https://blog.csdn.net/kk185800961/article/details/49725903

  GUI的使用~https://www.cnblogs.com/lyhabc/p/3475132.html

 

posted @   郭大侠1  阅读(1358)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2018-06-04 (3.3)常用知识-索引使用、维护与填充因子
2018-06-04 (3.2)常用知识-字符串处理
2018-06-04 (3.1)常用知识-日期处理
2018-06-04 基于Sql Server 2008的分布式数据库的实践
2018-06-04 (2.5)DDL增强功能-触发器trigger
2018-06-04 将expression转化为数据类型int时发生算术溢出错误
2018-06-04 Agent XPs disable
点击右上角即可分享
微信分享提示