SQL Server 数据库资源占用分析

   1.1 查看数据库当前用户连接数和最耗时的查询

USE master
GO
--看一下当前的数据库用户连接有多少
--如果要指定数据库就把注释去掉
SELECT * FROM sys.[sysprocesses] WHERE [spid]>50 --AND DB_NAME([dbid])='gposdb'
SELECT * FROM [sys].[dm_exec_sessions] WHERE [session_id]>50


--使用下面语句看一下各项指标是否正常,是否有阻塞,这个语句选取了前10个最耗CPU时间的会话
--可以指定具体分析的数据库
SELECT TOP 10
  [session_id],
  [request_id],
  [start_time] AS '开始时间',
  [status] AS '状态',
  [command] AS '命令',
  dest.[text] AS 'sql语句', 
  DB_NAME([database_id]) AS '数据库名',
 [blocking_session_id] AS '正在阻塞其他会话的会话ID',
 [wait_type] AS '等待资源类型',
 [wait_time] AS '等待时间',
 [wait_resource] AS '等待的资源',
 [reads] AS '物理读次数',
 [writes] AS '写次数',
 [logical_reads] AS '逻辑读次数',
 [row_count] AS '返回结果行数'
FROM sys.[dm_exec_requests] AS der 
 CROSS APPLY 
 sys.[dm_exec_sql_text](der.[sql_handle]) AS dest 
WHERE [session_id]>50 --AND DB_NAME(der.[database_id])='QQXYSocialBusinessDB'  
ORDER BY [cpu_time] DESC



--在SSMS里选择以文本格式显示结果
 SELECT TOP 10 dest.[text] AS 'sql语句'
 FROM sys.[dm_exec_requests] AS der 
 CROSS APPLY 
 sys.[dm_exec_sql_text](der.[sql_handle]) AS dest 
 WHERE [session_id]>50  
 ORDER BY [cpu_time] DESC
View Code

   1.2 检查是否有sql语句等待资源

/*
如果SQLSERVER存在要等待的资源,那么执行下面语句就会显示出会话中有多少个worker在等待;
如果当前SQLSERVER里面没有任何等待资源,那么下面的SQL语句不会显示任何结果;
*/

SELECT TOP 10
   [session_id],
   [request_id],
   [start_time] AS '开始时间',
   [status] AS '状态',
   [command] AS '命令',
   dest.[text] AS 'sql语句', 
   DB_NAME([database_id]) AS '数据库名',
   [blocking_session_id] AS '正在阻塞其他会话的会话ID',
  der.[wait_type] AS '等待资源类型',
  [wait_time] AS '等待时间',
  [wait_resource] AS '等待的资源',
  [dows].[waiting_tasks_count] AS '当前正在进行等待的任务数',
  [reads] AS '物理读次数',
  [writes] AS '写次数',
  [logical_reads] AS '逻辑读次数',
  [row_count] AS '返回结果行数'
FROM sys.[dm_exec_requests] AS der 
INNER JOIN [sys].[dm_os_wait_stats] AS dows 
  ON der.[wait_type]=[dows].[wait_type]
CROSS APPLY 
sys.[dm_exec_sql_text](der.[sql_handle]) AS dest 
WHERE [session_id]>50  
ORDER BY [cpu_time] DESC
View Code

   1.3  查数据库服务器资源总数和已使用数

--查看CPU数和user scheduler数和最大工作线程数,检查worker是否用完也可以排查CPU占用情况

--查看最大工作线程数
SELECT cpu_count AS CPU数,scheduler_count AS user_scheduler数目
    ,max_workers_count AS 最大工作线程数
    ,(SELECT COUNT(0) FROM sys.dm_os_schedulers) AS 当前线程数 FROM sys.dm_os_sys_info

--查看机器上的所有schedulers包括user 和system
--通过下面语句可以看到worker是否用完,当达到最大线程数的时候就要检查blocking(阻塞)了

--SELECT
--    scheduler_address,
--    scheduler_id,
--    cpu_id,
--    status,
--    current_tasks_count,
--    current_workers_count,active_workers_count
--FROM sys.dm_os_schedulers



--查询CPU占用高的语句

SELECT TOP 10 total_worker_time/execution_count AS avg_cpu_cost, plan_handle, execution_count,
     (SELECT SUBSTRING(text, statement_start_offset/2 + 1,
        (CASE WHEN statement_end_offset = -1
           THEN LEN(CONVERT(nvarchar(max), text)) * 2
           ELSE statement_end_offset
        END - statement_start_offset)/2)
     FROM sys.dm_exec_sql_text(sql_handle)
     ) AS query_text
FROM sys.dm_exec_query_stats
ORDER BY [avg_cpu_cost] DESC
View Code

   1.4 查询缺失的索引

USE master
GO


--查询缺失索引

SELECT DatabaseName = DB_NAME(database_id)
     ,[Number Indexes Missing] = count(*) 
FROM sys.dm_db_missing_index_details
GROUP BY DB_NAME(database_id)
ORDER BY 2 DESC;


SELECT  TOP 10 
  [Total Cost]  = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0) 
  , avg_user_impact
  , TableName = statement
  , [EqualityUsage] = equality_columns 
  , [InequalityUsage] = inequality_columns
  , [Include Cloumns] = included_columns
FROM        sys.dm_db_missing_index_groups g 
INNER JOIN    sys.dm_db_missing_index_group_stats s 
    ON s.group_handle = g.index_group_handle 
INNER JOIN    sys.dm_db_missing_index_details d 
    ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC;
View Code

   1.5 查询表的字段及长度

declare @temp_tabels table(serial int,name NVARCHAR(500),xtype nvarchar(20))

insert @temp_tabels
select ROW_NUMBER() over(order by name) as serial,name,xtype=case when xtype='v' then 'view' when xtype='u' then 'table' end
from dbo.sysobjects where xtype in ('v','u')

--select * from @temp_tabels

declare @index int
declare @tablename nvarchar(50)
declare @tabletype nvarchar(10)
declare @temp_sql nvarchar(max)
declare @tablecount int
select @tablecount=count(serial) from @temp_tabels

set @index=1
set @temp_sql=''

while exists(select serial from @temp_tabels where serial=@index)
begin
    select @tablename=name,@tabletype=xtype from @temp_tabels where serial=@index
    -- insert @temp_tablematedata 
    if(@index=@tablecount)    
        set @temp_sql=@temp_sql + 'select ''' + @tablename + ''' as tablename,''' + @tabletype + ''' as tabletype,a.name as fieldname, P.Value as fieldDesc,b.name as fieldtype,fieldlength= case when b.name=''nvarchar'' then a.length/2 else a.length end from syscolumns  as a left join systypes as b on a.xtype=b.xusertype left join sys.extended_properties P on a.ID=P.major_id and a.colid=P.minor_id where id=OBJECT_ID(''' + @tablename + ''') '
    else
        set @temp_sql=@temp_sql + 'select ''' + @tablename + ''' as tablename,''' + @tabletype + ''' as tabletype,a.name as fieldname, P.Value as fieldDesc,b.name as fieldtype,fieldlength= case when b.name=''nvarchar'' then a.length/2 else a.length end from syscolumns  as a left join systypes as b on a.xtype=b.xusertype left join sys.extended_properties P on a.ID=P.major_id and a.colid=P.minor_id where id=OBJECT_ID(''' + @tablename + ''') union all '
    set @index=@index+1

    print @temp_sql
end

SET @temp_sql = ' select tablename,tabletype,fieldname,fielddesc
    , (case when fieldtype in(''varchar'',''nvarchar'') then fieldtype+''(''+convert(varchar(50),fieldlength)+'')'' else fieldtype end) as fieldtype 
    from ('+ @temp_sql +') AllTableInfo '


exec(@temp_sql)
View Code

 

posted @ 2021-02-05 11:21  Team_Leading  阅读(671)  评论(0编辑  收藏  举报