SQL SERVER 排查脚本
随着数据量和并发量的增大,数据库有时会遇到CPU,内存,IO 性能问题;整理了一下有关排查数据相关的SQL脚本,以便排查问题之用;
1,哪些SQL 消耗CPU
/* 查看哪些SQL语句消耗CPU,找出有问题的SQL语句进行优化,或者索引优化*/ SELECT TOP 50 total_worker_time/1000 as '总消耗CPU 时间(ms)', execution_count '运行次数', qs.total_worker_time/qs.execution_count/1000. as '平均消耗CPU 时间(ms)', SUBSTRING(qt.text,qs.statement_start_offset/2+1, (case when qs.statement_end_offset = -1 then DATALENGTH(qt.text) else qs.statement_end_offset end -qs.statement_start_offset)/2 + 1) as '使用CPU的语法', qt.text '完整语法', qt.dbid, dbname=db_name(qt.dbid), qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName from sys.dm_exec_query_stats qs cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt order by total_worker_time desc
2, 查看SQL 阻塞进程
/***高并发情况下,容易产生进程阻塞,查看阻塞的SQL**/ SELECT t1.request_session_id AS 'wait_sid' , t1.resource_type AS '锁类型' , DB_NAME(resource_database_id) AS '库明称' , t1.request_mode AS 'wait锁类型' , t2.wait_duration_ms AS 'wait_time_ms' , ( SELECT text FROM sys.dm_exec_requests AS r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) WHERE r.session_id = t1.request_session_id ) AS 'wait_run_batch' , ( SELECT SUBSTRING(qt.text, r.statement_start_offset / 2 + 1, ( CASE WHEN r.statement_end_offset = -1 THEN DATALENGTH(qt.text) ELSE r.statement_end_offset END - r.statement_start_offset ) / 2 + 1) FROM sys.dm_exec_requests AS r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS qt WHERE r.session_id = t1.request_session_id ) AS 'wait 运行的SQL语句' , t2.blocking_session_id AS '锁定sid' , ( SELECT text FROM sys.sysprocesses AS p CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) WHERE p.spid = t2.blocking_session_id ) AS '锁定SQL' FROM sys.dm_tran_locks AS t1 INNER JOIN sys.dm_os_waiting_tasks AS t2 ON t1.lock_owner_address = t2.resource_address
3, SQL SERVER 后台连接情况
--请求 select s.session_id, s.status,db_name(r.database_id) as database_name, s.login_name,s.login_time, s.host_name, c.client_net_address,c.client_tcp_port,s.program_name, r.cpu_time, r.reads, r.writes,c.num_reads,c.num_writes, s.client_interface_name, s.last_request_start_time, s.last_request_end_time, c.connect_time, c.net_transport, c.net_packet_size, r.start_time, r.status, r.command, r.blocking_session_id, r.wait_type, r.wait_time, r.last_wait_type, r.wait_resource, r.open_transaction_count, r.percent_complete,r.granted_query_memory from Sys.dm_exec_requests r with(nolock) right outer join Sys.dm_exec_sessions s with(nolock) on r.session_id = s.session_id right outer join Sys.dm_exec_connections c with(nolock) on s.session_id = c.session_id where s.session_id >50 order by s.session_id --用户连接 select login_name,COUNT(0) user_count from Sys.dm_exec_requests r with(nolock) right outer join Sys.dm_exec_sessions s with(nolock) on r.session_id = s.session_id right outer join Sys.dm_exec_connections c with(nolock) on s.session_id = c.session_id where s.session_id >50 group by login_name order by 2 DESC --机器连接 select s.host_name,c.client_net_address,COUNT(0) host_count from Sys.dm_exec_requests r with(nolock) right outer join Sys.dm_exec_sessions s with(nolock) on r.session_id = s.session_id right outer join Sys.dm_exec_connections c with(nolock) on s.session_id = c.session_id where s.session_id >50 group by host_name,client_net_address order by 3 DESC --进程状态 select s.status,COUNT(0) host_count from Sys.dm_exec_requests r with(nolock) right outer join Sys.dm_exec_sessions s with(nolock) on r.session_id = s.session_id right outer join Sys.dm_exec_connections c with(nolock) on s.session_id = c.session_id where s.session_id >50 group by s.status order by 2 DESC
4, 内存使用情况
--查看内存状态 SELECT m.total_physical_memory_kb, m.available_physical_memory_kb, m.total_page_file_kb, m.available_page_file_kb, m.system_memory_state_desc FROM sys.dm_os_sys_memory m --查看各内存对象使用内存情况 --在SQL SERVER 2012及以上版本运行 SELECT M.type, sum(M.virtual_memory_reserved_kb) AS VirtualMemoryReservedKB, SUM(M.virtual_memory_committed_kb) AS VirtualMemortCommitedKB, SUM(M.shared_memory_committed_kb) AS SharedMemroyCommittedKB, SUM(M.shared_memory_reserved_kb) AS SharedMemroyReservedKB, SUM(M.pages_kb) AS PagesKB FROM sys.dm_os_memory_clerks M GROUP BY M.type ORDER BY PagesKB DESC --查看各数据库的内存使用情况 SET TRAN ISOLATION LEVEL READ UNCOMMITTED SELECT ISNULL(DB_NAME(database_id), 'ResourceDb') AS DatabaseName , CAST(COUNT(row_count) * 8.0 / (1024.0) AS DECIMAL(28,2)) AS [Size (MB)] FROM sys.dm_os_buffer_descriptors GROUP BY database_id ORDER BY DatabaseName --查看数据库内存相关性能计数器 SELECT * , CAST(P.cntr_value*8.0/1024.0 AS INT) AS MemoryMB FROM sys.sysperfinfo p WHERE p.object_name LIKE '%SQLServer:Buffer Manager%' SELECT * , CAST(P.cntr_value*8.0/1024.0 AS INT) AS MemoryMB FROM sys.sysperfinfo p WHERE p.object_name LIKE '%SQLServer:Memory Manager%'
5,CPU 历史使用情况
/* 查询数据库服务器CPU利用率的历史情况,每一分钟统计一次,看看被各个程序占用情况 */ DECLARE @ts_now bigint = (SELECT cpu_ticks/(cpu_ticks/ms_ticks) FROM sys.dm_os_sys_info WITH (NOLOCK)); SELECT SQLProcessUtilization AS [SQL Server Process CPU Utilization], SystemIdle AS [System Idle Process], 100 - SystemIdle - SQLProcessUtilization AS [Other Process CPU Utilization], DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS [Event Time] FROM (SELECT record.value('(./Record/@id)[1]', 'int') AS record_id, record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') AS [SystemIdle], record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') AS [SQLProcessUtilization], [timestamp] FROM (SELECT [timestamp], CONVERT(xml, record) AS [record] FROM sys.dm_os_ring_buffers WITH (NOLOCK) WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' AND record LIKE N'%<SystemHealth>%') AS x) AS y ORDER BY record_id DESC OPTION (RECOMPILE);