SQL Server - 監控 - Running SQL 抓取

来源:https://www.cnblogs.com/Sylaro0/archive/2020/07/17/13331742.html
-Advertisement-
Play Games

當資料庫出現性能異常時,如何找出引起性能問題的SQL? SQL Server自帶trace & event只能抓取已執行完成的SQL,且無法抓取SQL運行過程中的狀態信息 通過SQL Server系統視圖可抓取正在運行的SQL和豐富的相關信息,如執行計劃,狀態信息等。將抓取到的數據存放在本地資料庫表 ...


 

 當資料庫出現性能異常時,如何找出引起性能問題的SQL?

 

  • SQL Server自帶trace & event只能抓取已執行完成的SQL,且無法抓取SQL運行過程中的狀態信息

 

  • 通過SQL Server系統視圖可抓取正在運行的SQL和豐富的相關信息,如執行計劃,狀態信息等。將抓取到的數據存放在本地資料庫表中,方便故障分析。

執行相關係統視圖:

sys.dm_exec_requests

sys.dm_exec_sessions

sys.dm_exec_sql_text

sys.dm_exec_query_plan

其他系統視圖:

sys.sysprocesses

sys.dm_db_session_space_usage

   

  系統視圖中信息非常豐富,多抓取一些有用的欄位便於後續的分析工作

各欄位含義詳見官方文檔

https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-requests-transact-sql?view=sql-server-ver15

 

 

 具體實現方法:

一、 創建一張表用於存放抓取到的Running SQL及其相關信息

USE [dba_monitor]
GO
CREATE TABLE [running_sql_monitor](
    [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Insert_Time] [datetime] NOT NULL DEFAULT (getdate()),
    [Start_Time] [datetime] NOT NULL,
    [R_S] [int] NULL,
    [session_id] [smallint] NOT NULL,
    [status] [nvarchar](30) NOT NULL,
    [wait_type] [nvarchar](60) NULL,
    [wait_resource] [nvarchar](256) NOT NULL,
    [wait_time] [int] NOT NULL,
    [cpu_cnt] [int] NULL,
    [b_spid] [smallint] NULL,
    [dbname] [nvarchar](128) NULL,
    [t_level] [smallint] NOT NULL,
    [o_t_c] [int] NOT NULL,
    [row_count] [bigint] NOT NULL,
    [parent_query] [nvarchar](max) NULL,
    [individual_query] [nvarchar](max) NULL,
    [QueryPlan_XML] [xml] NULL,
    [login_name] [nvarchar](128) NOT NULL,
    [host_name] [nvarchar](128) NULL,
    [program_name] [nvarchar](128) NULL,
    [client_interface_name] [nvarchar](32) NULL,
    [cpu_time] [int] NOT NULL,
    [logical_reads] [bigint] NOT NULL,
    [reads] [bigint] NOT NULL,
    [writes] [bigint] NOT NULL,
    [memory_usage] [int] NULL,
    [tempdb_user_objects_mb] [int] NULL,
    [tempdb_internal_objects_mb] [int] NULL,
    [login_time] [datetime] NOT NULL,
    [percent_complete] [real] NOT NULL
) ON [PRIMARY] 

GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'自增列' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'記錄插入時間' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'Insert_Time'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL執行開始時間' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'Start_Time'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL運行總時間(單位秒)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'R_S'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL使用的CPU核數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'cpu_cnt'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'被哪個session_id阻塞' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'b_spid'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'完整的SQL語句' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'parent_query'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'正在執行的SQL語句' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'individual_query'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL語句的執行計劃' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'QueryPlan_XML'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL中的用戶對象占用tempdb大小(單位MB)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'tempdb_user_objects_mb'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL中的內部對象占用tempdb大小(單位MB)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'running_sql_monitor', @level2type=N'COLUMN',@level2name=N'tempdb_internal_objects_mb'
GO

 

 

二、創建SQL Server JOB抓取Running SQL 

job step1、 抓取Running SQL

INSERT INTO dba_monitor..running_sql_monitor(
Start_Time, R_S, session_id, [status], wait_type, wait_resource, wait_time, cpu_cnt, b_spid, DBNAME, t_level, o_t_c, row_count, 
parent_query, individual_query, QueryPlan_XML, login_name, [host_name], [program_name], client_interface_name, cpu_time, logical_reads, reads, writes,
memory_usage, tempdb_user_objects_mb, tempdb_internal_objects_mb, login_time, percent_complete
 )
SELECT  r.start_time, DATEDIFF(s, r.start_time, GETDATE()) AS R_S, r.session_id,
        r.[status], r.wait_type, r.wait_resource,r.wait_time,
        x.counts AS cpu_cnt ,r.blocking_session_id AS b_spid,  
        DB_NAME(r.database_id) AS dbname,
        es.transaction_isolation_level AS t_level,r.open_transaction_count AS o_t_c, es.row_count,
        parent_query = qt.[text], 
        individual_query = SUBSTRING(qt.[text], (r.statement_start_offset / 2) + 1,((CASE WHEN r.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.[text])) * 2 
                                                                                ELSE r.statement_end_offset END - r.statement_start_offset) / 2) + 1), 
        QueryPlan_XML = (SELECT query_plan FROM  sys.dm_exec_query_plan(r.plan_handle)),
        es.login_name, es.host_name, es.program_name, es.client_interface_name,
        r.cpu_time, r.logical_reads, r.reads, r.writes, memory_usage,
        (su.user_objects_alloc_page_count * 8 /1024) AS tempdb_user_objects_mb, 
        (su.internal_objects_alloc_page_count * 8 /1024) AS tempdb_internal_objects_mb,
        es.login_time, r.percent_complete       
FROM    sys.dm_exec_requests AS r WITH(NOLOCK)
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS qt
INNER JOIN sys.dm_exec_sessions AS es WITH(NOLOCK) ON r.session_id = es.session_id
LEFT JOIN (SELECT spid,MAX(loginame)AS loginame,COUNT(0)AS counts FROM sys.sysprocesses WITH(NOLOCK) GROUP BY spid)  x ON x.spid=r.session_id
LEFT JOIN sys.dm_db_session_space_usage su on es.session_id=su.session_id
WHERE  es.is_user_process = 1 
AND es.session_Id <> @@SPID

 

job step2、為防止監控表過大,刪除7天前抓取到的數據(請根據實際情況設置JOB運行間隔時間,以及監控數據需要保留的時間周期,避免監控文件過大導致磁碟空間耗盡!!!

delete top(100) from dba_monitor..running_sql_monitor where Insert_Time < DATEADD(DAY, -7, CAST(GETDATE() as DATE))

 

 

 


 

分析在出現性能問題時抓取到的SQL,通過執行時長,SQL運行狀態,等待信息來確認哪些SQL是罪魁禍首(部分被抓取到SQL可能是受害者,由於其他SQL占用了的大量系統資源 或 長時間占用鎖資源)

希望能幫助到有需要的同學

 

   

                                                                                           

本文為原創,轉載請註明:https://www.cnblogs.com/Sylaro0/

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、什麼是USB USB的全稱是Universal Serial Bus,通用串列匯流排。它的出現主要是為了簡化個人電腦與外圍設備的連接,增加易用性。USB支持熱插拔,並且是即插即用的,另外,它還具有很強的可擴展性,傳輸速度也很快,這些特性使支持USB介面的電子設備更易用、更大眾化。 本文將從USB ...
  • 一 動靜分離概述 1.1 動靜分離介紹 為了提高網站的響應速度,減輕程式伺服器(Tomcat,Jboss等)的負載,對於靜態資源,如圖片、js、css等文件,可以在反向代理伺服器中進行緩存,這樣瀏覽器在請求一個靜態資源時,代理伺服器就可以直接處理,而不用將請求轉發給後端伺服器。對於用戶請求的動態文件 ...
  • 通常tomcat作為應用伺服器,我們不建議也不應該讓tomcat直接面向客戶端提供服務;因此進入tomcat的訪問就只有其他反代伺服器的請求了;如果說tomcat使用其他反代伺服器對外提供服務,那麼對於https的訪問就應該由代理伺服器端來實現,從代理伺服器到tomcat的訪問,我們應該還是使用h... ...
  • 首先去mysql官網下載mysql的離線rpm安裝包(https://downloads.mysql.com/archives/community/) 上傳到/data/rpm/mysql8.0目錄下 因為Mysql依賴於mariadb,所以我們先用rpm -qa | grep mariadb 查找 ...
  • 路漫漫其修遠兮,吾將上下而求索,又到了周末,我繼續帶各位看官學習回顧Mysql知識。 上次說到了流程式控制制函數,那就從流程式控制制函數來繼續學習吧! #五.流程式控制制函數 #1.if函數:if else的效果 IF(條件表達式,成立返回1,不成立返回2) #與Java三元運算相同SELECT IF(10>5 ...
  • select * from T_A a (nolock) where a.xh not in (select xh from T_B) 方法1:效果甚微 select * from T_A a (nolock) where not exists (select xh from T_B where x ...
  • 本文更新於2020-04-05,使用MySQL 5.7,操作系統為Deepin 15.4。 MySQL體繫結構 MySQL實例由一組後臺線程、一些記憶體塊和若幹服務線程組成。 後臺線程包括: 主線程:主要負責將臟緩存頁刷新到數據文件,執行purge操作,觸發檢查點,合併插入緩衝區等。 IO線程: in ...
  • Redis 6.0 新特性 ACL 介紹 Intro 在 Redis 6.0 中引入了 ACL(Access Control List) 的支持,在此前的版本中 Redis 中是沒有用戶的概念的,其實沒有辦法很好的控制許可權,redis 6.0 開始支持用戶,可以給每個用戶分配不同的許可權來控制許可權。 ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...