文章目录
- 一、系统表详解
- 1.1 dm_exec_query_stats
- 1.2 dm_exec_sql_text
- 1.3 dm_exec_requests
- 二、问SQL排查常用语句
对于SQL Server的慢SQL信息排查,我们可以利用一些系统自带的统计信息表来帮助我们进行问题SQL定位。
一、系统表详解
1.1 dm_exec_query_stats
该表记录了SQL Server中相关的执行计划的统计信息,从该表中我们可以从不同的维度分析是否存在一些资源消耗较大的SQL。
重点关注字段及其含义:
- sql_handle : SQL唯一标识,可通过该信息在sys.dm_exec_sql_text中查看具体的SQL文本信息
- plan_handle : SQL执行计划唯一标识,可通过该信息在sys.dm_exec_query_plan 中查看具体的SQL执行计划信息
- creation_time : 执行计划编译时间
- last_execution_time : 执行计划最近一次执行时间
- execution_count : 自编译以来执行次数
- total_worker_time : 自编译以来执行消耗总CPU时间
- last_worker_time : 自编译以来最近一次CPU耗时
- min_worker_time : 自编译以来单次执行的最小CPU耗时
- max_worker_time : 自编译以来单次执行的最大CPU时间
- total_physical_reads : 自编译以来执行消耗总物理读次数
- total_logical_writes : 自编译以来执行消耗总逻辑写次数
- total_logical_reads :自编译以来执行消耗总逻辑读次数
- total_elapsed_time :自编译以来执行总耗时
- total_rows :查询返回的总行数
1.2 dm_exec_sql_text
根据sql_handle的标识来查看对应的SQL文本,查询语句如下:
sys.dm_exec_sql_text(sql_handle | plan_handle)
- dbid :数据库唯一标识ID
- text :SQL文本
1.3 dm_exec_requests
- session_id : 会话ID
- start_time : 会话开始时间
- status : 会话状态
- command : 会话执行命令类型
- sql_handle : 会话执行SQL唯一标识
- database_id : 数据库ID
- user_id : 数据库用户ID
- blocking_session_id : 阻塞当前会话的会话ID,NULL或0表示当前会话未出现阻塞
- wait_type : 若当前会话出现阻塞,阻塞等待的类型
- wait_time : 阻塞等待时间
- wait_resource : 等待资源信息
- transaction_id : 事物ID
- percent_complete : 某些维护操作完成百分比
- cpu_time : 会话请求CPU时间消耗
- total_elapsed_time : 会话请求耗时消耗
- reads : 会话请求物理读消耗
- writes : 会话请求写消耗
- logical_reads : 会话请求逻辑读消耗
- transaction_isolation_level : 事物隔离级别
二、问SQL排查常用语句
1、查找平均CPU时间消耗 TOP N 查询
SELECT TOP 5 query_stats.query_hash AS "Query Hash",
SUM(query_stats.total_worker_time) / SUM(query_stats.execution_count) AS "Avg CPU Time",
MIN(query_stats.statement_text) AS "Statement Text"
FROM
(SELECT QS.*,
SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
((CASE statement_end_offset
WHEN -1 THEN DATALENGTH(ST.text)
ELSE QS.statement_end_offset END
- QS.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS QS
CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
GROUP BY query_stats.query_hash
ORDER BY 2 DESC;
2、查找平均查询耗时 TOP N 查询
SELECT TOP 5 query_stats.query_hash AS "Query Hash",
SUM(query_stats.total_elapsed_time) / SUM(query_stats.execution_count) AS "Avg Query Time",
MIN(query_stats.statement_text) AS "Statement Text"
FROM
(SELECT QS.*,
SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
((CASE statement_end_offset
WHEN -1 THEN DATALENGTH(ST.text)
ELSE QS.statement_end_offset END
- QS.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS QS
CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
GROUP BY query_stats.query_hash
ORDER BY 2 DESC;
3、查看指定sql_handle对应的SQL语句
SELECT * FROM sys.dm_exec_sql_text(${sql_handle}) -- modify this value with your actual sql_handle
4、利用cross apply结合其他系统表查看问题SQL信息
select DB_NAME(t.dbid),t.text,r.status,r.start_time,r.command,r.session_id,r.wait_time,r.last_wait_type
from sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
where r.database_id=DB_ID('nuskincsm')