Heim >Datenbank >MySQL-Tutorial >SQLSERVER排查CPU占用高的情况

SQLSERVER排查CPU占用高的情况

WBOY
WBOYOriginal
2016-06-07 15:44:491510Durchsuche

操作系统是Windows2008R2 ,数据库是SQL2008R2 64位 64G内存,16核CPU 硬件配置还是比较高的,他说服务器运行的是金蝶K3软件,数据库实例里有多个数据库 他说是这几天才出现的,而且在每天的某一个时间段才会出现CPU占用高的情况 内存占用也很高,占用了30个G

操作系统是Windows2008R2 ,数据库是SQL2008R2 64位

64G内存,16核CPU

硬件配置还是比较高的,他说服务器运行的是金蝶K3软件,数据库实例里有多个数据库

他说是这几天才出现的,而且在每天的某一个时间段才会出现CPU占用高的情况

内存占用也很高,占用了30个G

SQLSERVER排查CPU占用高的情况

SQLSERVER排查CPU占用高的情况

-----------------------------------------------华丽的分割线-------------------------------------------------------

一般排查都是用下面的脚本,一般会用到三个视图sys.sysprocesses ,dm_exec_sessions ,dm_exec_requests

<span>1 <span>USE<span> master
<span>2 <span>GO
<span>3 <span>--<span>如果要指定数据库就把注释去掉
<span>4 <span>SELECT <span>* <span>FROM sys.<span>[<span>sysprocesses<span>] <span>WHERE <span>[<span>spid<span>]<span>><span>50 <span>--<span>AND DB_NAME([dbid])='gposdb'
<span>5 <span>SELECT <span>COUNT(<span>*) <span>FROM <span>[<span>sys<span>].<span>[<span>dm_exec_sessions<span>] <span>WHERE <span>[<span>session_id<span>]<span>><span>50</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

看一下当前的数据库用户连接有多少

然后使用下面语句看一下各项指标是否正常,是否有阻塞,这个语句选取了前10个最耗CPU时间的会话

<span> 1 <span>SELECT <span>TOP <span>10
<span> 2 <span>[<span>session_id<span>]<span>,
<span> 3 <span>[<span>request_id<span>]<span>,
<span> 4 <span>[<span>start_time<span>] <span>AS <span>'<span>开始时间<span>'<span>,
<span> 5 <span>[<span>status<span>] <span>AS <span>'<span>状态<span>'<span>,
<span> 6 <span>[<span>command<span>] <span>AS <span>'<span>命令<span>'<span>,
<span> 7 dest.<span>[<span>text<span>] <span>AS <span>'<span>sql语句<span>'<span>, 
<span> 8 <span>DB_NAME(<span>[<span>database_id<span>]) <span>AS <span>'<span>数据库名<span>'<span>,
<span> 9 <span>[<span>blocking_session_id<span>] <span>AS <span>'<span>正在阻塞其他会话的会话ID<span>'<span>,
<span>10 <span>[<span>wait_type<span>] <span>AS <span>'<span>等待资源类型<span>'<span>,
<span>11 <span>[<span>wait_time<span>] <span>AS <span>'<span>等待时间<span>'<span>,
<span>12 <span>[<span>wait_resource<span>] <span>AS <span>'<span>等待的资源<span>'<span>,
<span>13 <span>[<span>reads<span>] <span>AS <span>'<span>物理读次数<span>'<span>,
<span>14 <span>[<span>writes<span>] <span>AS <span>'<span>写次数<span>'<span>,
<span>15 <span>[<span>logical_reads<span>] <span>AS <span>'<span>逻辑读次数<span>'<span>,
<span>16 <span>[<span>row_count<span>] <span>AS <span>'<span>返回结果行数<span>'
<span>17 <span>FROM sys.<span>[<span>dm_exec_requests<span>] <span>AS<span> der 
<span>18 <span>CROSS<span> APPLY 
<span>19 sys.<span>[<span>dm_exec_sql_text<span>](der.<span>[<span>sql_handle<span>]) <span>AS<span> dest 
<span>20 <span>WHERE <span>[<span>session_id<span>]<span>><span>50 <span>AND <span>DB_NAME(der.<span>[<span>database_id<span>])<span>=<span>'<span>gposdb<span>'  
<span>21 <span>ORDER <span>BY <span>[<span>cpu_time<span>] <span>DESC</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>


如果想看具体的SQL语句可以执行下面的SQL语句,记得在SSMS里选择以文本格式显示结果

<span>1 <span>--<span>在SSMS里选择以文本格式显示结果
<span>2 <span>SELECT <span>TOP <span>10 
<span>3 dest.<span>[<span>text<span>] <span>AS <span>'<span>sql语句<span>'
<span>4 <span>FROM sys.<span>[<span>dm_exec_requests<span>] <span>AS<span> der 
<span>5 <span>CROSS<span> APPLY 
<span>6 sys.<span>[<span>dm_exec_sql_text<span>](der.<span>[<span>sql_handle<span>]) <span>AS<span> dest 
<span>7 <span>WHERE <span>[<span>session_id<span>]<span>><span>50  
<span>8 <span>ORDER <span>BY <span>[<span>cpu_time<span>] <span>DESC</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

SQLSERVER排查CPU占用高的情况

模拟了一些耗CPU时间的动作

SQLSERVER排查CPU占用高的情况

SQLSERVER排查CPU占用高的情况

SQLSERVER排查CPU占用高的情况

-----------------------------------------华丽的分割线-----------------------------------------------------------

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

<span>1 <span>--<span>查看CPU数和user scheduler数目
<span>2 <span>SELECT cpu_count,scheduler_count <span>FROM<span> sys.dm_os_sys_info
<span>3 <span>--<span>查看最大工作线程数
<span>4 <span>SELECT max_workers_count <span>FROM sys.dm_os_sys_info</span></span></span></span></span></span></span></span></span></span></span></span></span>

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


对照下面这个表
各种CPU和SQLSERVER版本组合自动配置的最大工作线程数
CPU数                 32位计算机                        64位计算机
  8                        288                                   576
 16                       352                                   704
 32                       480                                   960

<span>1 <span>SELECT
<span>2 <span>scheduler_address,
<span>3 <span>scheduler_id,
<span>4 <span>cpu_id,
<span>5 <span>status,
<span>6 <span>current_tasks_count,
<span>7 <span>current_workers_count,active_workers_count
<span>8 <span>FROM sys.dm_os_schedulers</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

 如果大家有什么需要补充的,或者文章有不正确的,欢迎大家拍砖!!

----------------------------------------------------------------------------------------------

 2013-6-15 做了一下补充,如果SQLSERVER存在要等待的资源,那么执行下面语句就会显示出会话中有多少个worker在等待

结合[sys].[dm_os_wait_stats]视图,如果当前SQLSERVER里面没有任何等待资源,那么下面的SQL语句不会显示任何结果

<span> 1 <span>SELECT <span>TOP <span>10
<span> 2  <span>[<span>session_id<span>]<span>,
<span> 3  <span>[<span>request_id<span>]<span>,
<span> 4  <span>[<span>start_time<span>] <span>AS <span>'<span>开始时间<span>'<span>,
<span> 5  <span>[<span>status<span>] <span>AS <span>'<span>状态<span>'<span>,
<span> 6  <span>[<span>command<span>] <span>AS <span>'<span>命令<span>'<span>,
<span> 7  dest.<span>[<span>text<span>] <span>AS <span>'<span>sql语句<span>'<span>, 
<span> 8  <span>DB_NAME(<span>[<span>database_id<span>]) <span>AS <span>'<span>数据库名<span>'<span>,
<span> 9  <span>[<span>blocking_session_id<span>] <span>AS <span>'<span>正在阻塞其他会话的会话ID<span>'<span>,
<span>10  der.<span>[<span>wait_type<span>] <span>AS <span>'<span>等待资源类型<span>'<span>,
<span>11  <span>[<span>wait_time<span>] <span>AS <span>'<span>等待时间<span>'<span>,
<span>12  <span>[<span>wait_resource<span>] <span>AS <span>'<span>等待的资源<span>'<span>,
<span>13  <span>[<span>dows<span>].<span>[<span>waiting_tasks_count<span>] <span>AS <span>'<span>当前正在进行等待的任务数<span>'<span>,
<span>14  <span>[<span>reads<span>] <span>AS <span>'<span>物理读次数<span>'<span>,
<span>15  <span>[<span>writes<span>] <span>AS <span>'<span>写次数<span>'<span>,
<span>16  <span>[<span>logical_reads<span>] <span>AS <span>'<span>逻辑读次数<span>'<span>,
<span>17  <span>[<span>row_count<span>] <span>AS <span>'<span>返回结果行数<span>'
<span>18  <span>FROM sys.<span>[<span>dm_exec_requests<span>] <span>AS<span> der 
<span>19  <span>INNER <span>JOIN <span>[<span>sys<span>].<span>[<span>dm_os_wait_stats<span>] <span>AS<span> dows 
<span>20  <span>ON der.<span>[<span>wait_type<span>]<span>=<span>[<span>dows<span>].<span>[<span>wait_type<span>]
<span>21  <span>CROSS<span> APPLY 
<span>22  sys.<span>[<span>dm_exec_sql_text<span>](der.<span>[<span>sql_handle<span>]) <span>AS<span> dest 
<span>23  <span>WHERE <span>[<span>session_id<span>]<span>><span>50  
<span>24  <span>ORDER <span>BY <span>[<span>cpu_time<span>] DESC</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

 比如我当前执行了查询SalesOrderDetail_test表100次,由于表数据非常多,所以SSMS需要把SQLSERVER执行的结果慢慢的取走,

造成了ASYNC_NETWORK_IO等待

<span>1 <span>USE <span>[<span>AdventureWorks<span>]
<span>2 <span>GO
<span>3 <span>SELECT <span>* <span>FROM dbo.<span>[<span>SalesOrderDetail_test<span>]
<span>4 <span>GO <span>100</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

SQLSERVER排查CPU占用高的情况

------------------------------------------------------------------------------------------------

经过排查和这几天的观察情况,确定是某些表缺失索引导致,现在在这些表上增加了索引,问题解决了

<span>1 <span>select <span>* <span>from t_AccessControl        <span>--<span>权限控制表权限控制
<span>2 <span>select <span>* <span>from t_GroupAccess            <span>--<span>用户组权限表用户组权限
<span>3 <span>select <span>* <span>from t_GroupAccessType        <span>--<span>用户组权限类表用户组权限类
<span>4 <span>select <span>* <span>from t_ObjectAccess        <span>--<span>对象权限表对象权限
<span>5 <span>select <span>* <span>from t_ObjectAccessType    <span>--<span>对象权限类型表对象权限类型
<span>6 <span>select <span>* <span>from t_ObjectType            <span>--<span>对象类型表对象类型</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

查询CPU占用高的语句

<span> 1 <span>SELECT <span>TOP <span>10
<span> 2    total_worker_time<span>/execution_count <span>AS<span> avg_cpu_cost, plan_handle,
<span> 3 <span>   execution_count,
<span> 4    (<span>SELECT <span>SUBSTRING(<span>text, statement_start_offset<span>/<span>2 <span>+ <span>1<span>,
<span> 5       (<span>CASE <span>WHEN statement_end_offset <span>= <span>-<span>1
<span> 6          <span>THEN <span>LEN(<span>CONVERT(<span>nvarchar(<span>max), <span>text)) <span>* <span>2
<span> 7          <span>ELSE<span> statement_end_offset
<span> 8       <span>END <span>- statement_start_offset)<span>/<span>2<span>)
<span> 9    <span>FROM sys.dm_exec_sql_text(sql_handle)) <span>AS<span> query_text
<span>10 <span>FROM<span> sys.dm_exec_query_stats
<span>11 <span>ORDER <span>BY <span>[<span>avg_cpu_cost<span>] <span>DESC</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

SQLSERVER排查CPU占用高的情况

查询缺失索引

<span>1 <span>SELECT 
<span>2     DatabaseName <span>= <span>DB_NAME<span>(database_id)
<span>3     ,<span>[<span>Number Indexes Missing<span>] <span>= <span>count(<span>*<span>) 
<span>4 <span>FROM<span> sys.dm_db_missing_index_details
<span>5 <span>GROUP <span>BY <span>DB_NAME<span>(database_id)
<span>6 <span>ORDER <span>BY <span>2 <span>DESC;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

<span> 1 <span>SELECT  <span>TOP <span>10 
<span> 2         <span>[<span>Total Cost<span>]  <span>= <span>ROUND(avg_total_user_cost <span>* avg_user_impact <span>* (user_seeks <span>+ user_scans),<span>0<span>) 
<span> 3 <span>        , avg_user_impact
<span> 4         , TableName <span>=<span> statement
<span> 5         , <span>[<span>EqualityUsage<span>] <span>=<span> equality_columns 
<span> 6         , <span>[<span>InequalityUsage<span>] <span>=<span> inequality_columns
<span> 7         , <span>[<span>Include Cloumns<span>] <span>=<span> included_columns
<span> 8 <span>FROM<span>        sys.dm_db_missing_index_groups g 
<span> 9 <span>INNER <span>JOIN<span>    sys.dm_db_missing_index_group_stats s 
<span>10        <span>ON s.group_handle <span>=<span> g.index_group_handle 
<span>11 <span>INNER <span>JOIN<span>    sys.dm_db_missing_index_details d 
<span>12        <span>ON d.index_handle <span>=<span> g.index_handle
<span>13 <span>ORDER <span>BY <span>[<span>Total Cost<span>] <span>DESC;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

SQLSERVER排查CPU占用高的情况

SQLSERVER排查CPU占用高的情况

定位问题后,新建非聚集索引

<span>1 <span>CREATE <span>NONCLUSTERED <span>INDEX IX_t_AccessControl_F4 <span>ON<span> dbo.t_AccessControl
<span>2 <span>(
<span>3 <span>    FObjectType
<span>4 )include(<span>[<span>FUserID<span>], <span>[<span>FAccessType<span>], <span>[<span>FAccessMask<span>]) <span>WITH( STATISTICS_NORECOMPUTE <span>= <span>OFF, IGNORE_DUP_KEY <span>= <span>OFF, ALLOW_ROW_LOCKS <span>= <span>ON, ALLOW_PAGE_LOCKS <span>= <span>ON) <span>ON <span>[<span>PRIMARY<span>]
<span>5 <span>GO
<span>6 
<span>7 <span>drop <span>index IX_t_AccessControl_F4 <span>on t_AccessControl</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

 CPU占用恢复正常

SQLSERVER排查CPU占用高的情况

跟踪模板和跟踪文件下载,请使用SQL2008R2 版本:files.cnblogs.com/lyhabc/跟踪模板和trace.rar

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn