如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志)

如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志)

SQL Server一直以来被人诟病的一个问题是缺少了像MySQL的慢日志功能,程序员和运维无法知道数据库过去历史的慢查询语句。

因为SQLServer默认是不捕获过去历史的长时间阻塞的SQL语句,导致大家都认为SQL Server没有历史慢日志功能

其实SQLServer提供了扩展事件让用户自己去捕获过去历史的长时间阻塞的SQL语句,但是因为不是默认出厂配置并且设置扩展事件对初级用户有一定难度,这里可以说不得不是一个遗憾,希望后续版本的SQL Server可以默认设置好慢日志的相关扩展事件,用初级用户也可以快速上手。


话不多说,这个文章主要讲述设置慢日志的扩展事件的步骤,并且把慢日志提供第三方程序读取以提供报表功能。

 

扩展事件介绍

SQL Server 扩展事件(Extended Events,简称 XE)是从 SQL Server 2008 开始引入的一种轻量级、高度可定制的事件处理系统,
旨在帮助数据库管理员和开发人员更好地监控、调试和优化 SQL Server 的性能。
扩展事件可以用于捕获和分析 SQL Server 内部发生的各种事件,以便识别和解决性能瓶颈和问题。

扩展事件优点包括轻量级、统一事件处理框架和集成性。事件设计对系统性能影响最小,确保在高负载环境下也能稳定运行。
扩展事件可以与 SQL Server Profiler 和 SQL Server Audit 结合使用,为用户提供全面的诊断和监控工具。

 


 

 

实验步骤

创建环境所需的数据库和表

--窗口1
--建表USE testdb
GOCREATE TABLE Account(id INT, name NVARCHAR(200))INSERT INTO [dbo].[Account]
SELECT 1,'Lucy'
UNION ALL
SELECT 2,'Tom'
UNION ALL
SELECT 3,'Marry'--查询
SELECT * FROM [dbo].[Account]

 

 创建扩展事件

 

 输入扩展事件名称

 

 不要使用模版

 

事件库搜索block,选择blocked_process_report

 

确认事件

 

选择你需要的字段

这里选择client_app_name、client_hostname、database_id、database_name、plan_handle、query_hash、request_id、session_id、sql_text字段

当然你可以勾选自己想要的字段,这里只是抛砖引玉

直接下一步

这里需要注意的是,扩展事件日志不能全量保存,所以用户需要考虑好保留多长时间的扩展事件,假设一天可以产生的扩展事件大小为1GB,那么每个扩展事件文件大小1GB,最多5个扩展事件文件意味着你不能查询到5天之前的数据

比如你不能查询到前面第8天的扩展事件,扩展事件是滚动利用的。

扩展事件创建情况预览

小提示:你可以点击script生成这个扩展事件的create脚本,那么其他服务器就不用这样用界面去创建这么繁琐了。

生成出来的扩展事件

CREATE EVENT SESSION [slowquerylog]
ON SERVERADD EVENT sqlserver.blocked_process_report(ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.request_id,sqlserver.session_id,sqlserver.sql_text))ADD TARGET package0.event_file(SET filename = N'E:\DBExtentEvent\slowquerylog.xel')
WITH
(STARTUP_STATE = ON
);
GO

完成

你可以勾选

a.扩展事件创建完成之后立刻启动

b.查看实时捕获的数据

立刻启动扩展事件

 

一定要设置locked process threshold,否则无办法捕获慢SQL语句,这个选项类似于MySQL的long_query_time参数

locked process threshold是SQL Server2005推出的一个选项,下面设置阻塞10秒就会记录

--窗口2
--locked process threshold是SQL Server2005推出的一个选项--设置阻塞进程阈值
sp_configure 'show advanced options', 1 ;  
GO  
RECONFIGURE ;  
GO  
sp_configure 'blocked process threshold', 10 ;   --10秒
GO  
RECONFIGURE ;  
GO  

执行一个update语句,不要commit

--窗口3
USE testdb;
GOBEGIN tran
update Account
set name ='Test'
where ID = 2--commit

查询数据

-- 窗口4
USE testdb;
GO-- 这个查询会被窗口3中的事务阻塞
SELECT * FROM Account
WHERE ID = 2

 

执行完毕之后,你可以看到扩展事件已经记录下来了 

双击查看详细的会话里面的语句

可以很清楚的看到谁是被blocked的语句,谁是主动blocking的语句也就是源头

同时可以看到扩展事件已经记录到xel文件

 


 

使用其他编程语言制作慢查询日志报表

微软提供了使用 SQL Server Management Studio (SSMS) 和 T-SQL 查询扩展事件 XEL 文件内容的 API。

我们可以使用 sys.fn_xe_file_target_read_file 函数来读取 XEL 文件中的内容。
然后,你可以将这些数据导出为其他编程语言可以处理的格式

SQL语句

-- 查询扩展事件 XEL 文件内容
SELECT event_data.value('(event/@name)[1]', 'VARCHAR(50)') AS event_name,event_data.value('(event/@timestamp)[1]', 'DATETIME2') AS event_timestamp,event_data.value('(event/data[@name="duration"]/value)[1]', 'INT') AS duration,event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'VARCHAR(255)') AS client_app_name,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'VARCHAR(255)') AS client_hostname,event_data.value('(event/action[@name="database_name"]/value)[1]', 'VARCHAR(255)') AS database_name,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(MAX)') AS sql_text
FROM sys.fn_xe_file_target_read_file('E:\DBExtentEvent\slowquerylog*.xel', NULL, NULL, NULL) AS t
CROSS APPLY t.event_data.nodes('event') AS XEvent(event_data);



使用 Python 读取 XEL 文件内容
使用 pandas 库和pyodbc驱动程序从 SQL Server 导出数据并在 Python 中进行处理。
以下是一个示例脚本

import pyodbc
import pandas as pd# 设置数据库连接
conn = pyodbc.connect('DRIVER={SQL Server};''SERVER=your_server_name;''DATABASE=your_database_name;''UID=your_username;''PWD=your_password'
)# 查询 XEL 文件内容
query = """
SELECT event_data.value('(event/@name)[1]', 'VARCHAR(50)') AS event_name,event_data.value('(event/@timestamp)[1]', 'DATETIME2') AS event_timestamp,event_data.value('(event/data[@name="duration"]/value)[1]', 'INT') AS duration,event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'VARCHAR(255)') AS client_app_name,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'VARCHAR(255)') AS client_hostname,event_data.value('(event/action[@name="database_name"]/value)[1]', 'VARCHAR(255)') AS database_name,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(MAX)') AS sql_text
FROM sys.fn_xe_file_target_read_file('E:\DBExtentEvent\slowquerylog*.xel', NULL, NULL, NULL) AS t
CROSS APPLY t.event_data.nodes('event') AS XEvent(event_data);
"""# 使用 pandas 读取数据
df = pd.read_sql(query, conn)# 关闭数据库连接
conn.close()# 显示数据
print(df)# 将数据保存为 CSV 文件
df.to_csv('slowquerylog.csv', index=False)

 

这里的一个问题是,你不能直接读取XEL文件,本身XEL文件是一个二进制文件,必须挂接到在线SQL Server实例(任何SQL Server实例都可以,不一定是生产库的那一台SQL Server实例)

 

 

另外一个方法是使用 PowerShell 中的 Microsoft.SqlServer.XEvent.Linq.QueryableXEventData 类直接解析 XEL 文件,不用挂接到SQL Server实例

读取 XEL 文件的内容,然后导出CSV文件,让其他编程语言读取

 

Step 1: 创建 PowerShell 脚本 ReadXELFile.ps1

# 加载所需的程序集
Add-Type -Path "C:\Program Files\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.XEvent.Linq.dll"# 定义XEL文件路径
$xelFilePath = "E:\DBExtentEvent\slowquerylog*.xel"# 创建XEventData对象
$events = New-Object Microsoft.SqlServer.XEvent.Linq.QueryableXEventData($xelFilePath)# 初始化一个空数组来存储事件数据
$eventDataList = @()# 遍历每个事件并提取所需的字段
foreach ($event in $events) {$eventData = New-Object PSObject -Property @{EventName      = $event.NameTimestamp      = $event.TimestampDuration       = $event.Fields["duration"].ValueClientAppName  = $event.Actions["client_app_name"].ValueClientHostname = $event.Actions["client_hostname"].ValueDatabaseName   = $event.Actions["database_name"].ValueSqlText        = $event.Actions["sql_text"].Value}$eventDataList += $eventData
}# 将事件数据导出为CSV文件
$eventDataList | Export-Csv -Path "E:\DBExtentEvent\slowquerylog.csv" -NoTypeInformation

 

Step 2: Python 脚本 ReadCSVFile.py读取导出的 CSV 文件

import pandas as pd# 定义CSV文件路径
csv_file_path = "E:\\DBExtentEvent\\slowquerylog.csv"# 使用pandas读取CSV文件
df = pd.read_csv(csv_file_path)# 显示数据
print(df)

这个方法需要使用powershell,对于powershell不熟悉的朋友也是一个问题

 


 

总结

本文介绍了SQL Server的扩展捕获慢查询语句的功能,也就是我们所说的慢日志

另外,一定要设置“blocked process threshold”参数,否则设置了扩展事件也没有效果

总体来说,SQL Server作为一个企业级数据库,确实不像MySQL这种开源数据库简单直接

需要设置比较繁琐的扩展事件,对新手用户不太友好,门槛比较高,但是因为扩展事件功能非常强大

除了捕获慢查询还可以捕获死锁,索引缺失等性能问题,所以这个是在所难免的

 

 

 

 

 

本文版权归作者所有,未经作者同意不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/772892.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模拟退火学习笔记

骂谁罕见模拟退火学习笔记 前言 不知道为啥突然有闲情学这个... 模拟退火 (Simulated Annealing) , 简称 \(SA\) . 是一种基于随机化的算法,无门槛,主要是为了骗分... 不是正解!!!! 根据 爬山算法 的过程,我们发现:对于一个当前最优解附近的非最优解,爬山算法直接舍去…

录取查询

这道题赛时是想出来了,但是线段树出锅了,只得了20分。 首先根据题目我们可以得出,一个序列要是为T的子串,就必须满足以下三个条件。 1.该序列单调不降。如 ba肯定是不合法的。 2.该序列除去开头和结尾的字母,其他字母的数量必须为整个序列全部的该字母数量。 如 abbcba 选…

NaplesPU或NPU技术开发文档合成全部(修改版)

NaplesPU或NPU技术开发文档合成全部(修改版) http://www.naplespu.com/doc/index.php?title=Main_Page http://www.naplespu.com/ https://github.com/AlessandroCilardo/NaplesPU https://github.com/AlessandroCilardo/NaplesPU-toolchain http://www.naplespu.com/doc/in…

万恶资本主义观赏记录

万恶的资本主义到底如何没有体验过,我需要去体验,6月开始计划,参考了团队游项目,最终决定自由行。 行程从香港Hongkong飞伊斯坦布尔Istanbul,10小时,再飞纽约市New York City,10小时。再坐巴士去费城Philadelphia,一共15天。总结: 美国New York City,Philadelphia在美…

D. The Omnipotent Monster Killer

D. The Omnipotent Monster Killer题目大意: 有一棵树,树节点数不超过\(310^5\),每个节点的权值,定义为数组\(a(a_i<10^{12})\),初始\(sum=0\),每一轮执行如下操作:计算当前剩余所有的点权和,累计到\(sum\)中 任选若干个互不相邻的节点并移除重复这个操作直到树上没…

php 使用swoole 创建websocket服务

下载对应版本的swoole扩展, 我的php版本是7.4, 所以下载的swoole版本为4.8.* 地址如下https://pecl.php.net/package/swoole 通过源码编译安装, 可以参考官方文档https://wiki.swoole.com/zh-cn/#/environment 修改php.ini 开启扩展 extension=swoole.so 重启web服务器 php -m …

Labview笔记

1. 背景 Labview这个软件,从大学到现在,装了卸载,卸载了又装。来来回回不下10次了,那本大学时的教材Labview 2010基础教程,一直没丢,但也一直没看过。最近又装回来了,准备简单的系统性倒腾一下,当是个了解。一些杂项:快捷键:Ctrl+N:创建一个Labview项目 Ctrl+E:切换前…

二值图像

一、 二值图像概念 1. 二值图像含义二值图像(Binary Image)是指将图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。 二值图像是指在图像中,灰度等级只有两种,也就是说,图像中的任何像素点的灰度值均为0或者255,分别…

17、flask-图书简单馆项目

为了掌握模型可以练一下、以下是代码: app.py from App import create_appapp = create_app()if __name__ == __main__:app.run(debug=True)views.py from flask import Blueprint, render_template from datetime import datetime from .models import *#创建蓝图(路由) bl…

全网最适合入门的面向对象编程教程:25 类和对象的Python实现-Python判断输入数据类型

本文主要介绍了在使用Python面向对象编程时,如何使用type函数、isinstance函数和正则表达式三种方法判断用户输入数据类型,并对相关语法进行介绍。全网最适合入门的面向对象编程教程:25 类和对象的 Python 实现-Python 判断输入数据类型摘要: 本文主要介绍了在使用 Python …

[数据结构] 堆与堆排序

本文介绍了堆这种数据结构的性质,以及堆排序算法,最后介绍了堆的相关应用场景。这篇文章使用 JavaScript 语言进行相关代码的编写。数据结构——堆 heap 基本概念与性质 堆是一颗完全二叉树,根据父子节点之间值的大小关系可以分为:大根堆:每一个节点的值 大于或等于 其子节…