因老大回家生孩子去了,目前部门就我一个人去管理整个系统的日常运行,但是最近发现内部系统出现连接超时,打开查询页面缓慢,或者根本就直接不能访问了,于是通过查询
select * from sys.sysprocesses语句总共有可能达到130多个进程
通过到网上看到这个仁兄的帖子http://www.cnblogs.com/fygh/archive/2012/01/17/2324926.html 里面有一段脚本
select top 20 wait_type,SUM(waiting_tasks_count) waiting_tasks_count,就是统计数据库中等待的类型前20的,出现如下图到网上又搜了下,貌似LATCH_EX是因为磁盘读写速度不够,SOS_SCHEDULER_YIELD是因为CPu处理能力到了瓶颈吧?不是很清楚,我在想是不是系统中的sql脚本是不是没有经过优化的,我来了以后才给几个大表加索引,还只是个把栏位,然后很多语句都是select * ,不知道这种问题该怎么去解决,前4个月样子出现了这样的情况,后来是添加服你服务器内存,就好了很久,现在又出现了,不知道如何去改,因本人对数据库不是很熟,所以也无从下手,找到网上的这段sql代码
SUM(wait_time_ms)as total_wait_time_ms,
SUM(signal_wait_time_ms) as total_signal_wait_time_ms
from sys.dm_os_wait_stats with(nolock)
where wait_type not in
--system wait type
('LAZYWRITER_SLEEP','REQUEST_FOR_DEADLOCK_SEARCH','SQLTRACE_BUFFER_FLUSH',
'XE_TIMER_EVENT','FT_IFTS_SCHEDULER_IDLE_WAIT','LOGMGR_QUEUE','CHECKPOINT_QUEUE',
'SLEEP_TASK','BROKER_IO_FLUSH','BROKER_TASK_STOP','BROKER_TO_FLUSH','BROKER_EVENTHANDLER')
group by wait_type
order by total_wait_time_ms desc
SELECT s2.dbid ,可是不能执行,就是在标红色的地方提示Incorrect syntax near '.'.我也是醉了。。。。
DB_NAME(s2.dbid) AS [数据库名] ,
--s1.sql_handle ,
( SELECT TOP 1
SUBSTRING(s2.text, statement_start_offset / 2 + 1,
( ( CASE WHEN statement_end_offset = -1
THEN ( LEN(CONVERT(NVARCHAR(MAX), s2.text))
* 2 )
ELSE statement_end_offset
END ) - statement_start_offset ) / 2 + 1)
) AS [语句] ,
execution_count AS [执行次数] ,
last_execution_time AS [上次开始执行计划的时间] ,
total_worker_time AS [自编译以来执行所用的 CPU 时间总量(微秒)] ,
last_worker_time AS [上次执行计划所用的 CPU 时间(微秒)] ,
min_worker_time AS [单次执行期间曾占用的最小 CPU 时间(微秒)] ,
max_worker_time AS [单次执行期间曾占用的最大 CPU 时间(微秒)] ,
total_logical_reads AS [总逻辑读] ,
last_logical_reads AS [上次逻辑读] ,
min_logical_reads AS [最少逻辑读] ,
max_logical_reads AS [最大逻辑读] ,
total_logical_writes AS [总逻辑写] ,
last_logical_writes AS [上次逻辑写] ,
min_logical_writes AS [最小逻辑写] ,
max_logical_writes AS [最大逻辑写]
FROM sys.dm_exec_query_stats AS s1
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2WHERE s2.objectid IS NULL
ORDER BY last_worker_time DESC
丢失的索引也有语句,查询出来的结果是这样子的,求大神解决下
------解决思路----------------------
从你的第一个图来看,很有意思。
大部分的阻塞都是自己阻塞自己,另外,这些阻塞的情况都出现在,多线程的问题上。
比如71阻塞了他自己,他对应了2个线程,也就是kpid是不同的,其他的91更夸张,这个至少说明了,这些会话在执行sql语句时,都采用了并行的执行计划。
建议你查看一下,这些会话当前运行的是哪些语句:
查看会话71的sql语句
dbcc inputbuffer(71)
然后看看这个语句的执行计划,运行一下,看看是否很慢
------解决思路----------------------
刚才参考了这个 http://www.cnblogs.com/lyhabc/articles/3236984.html
看了你几个出现次数比较多的等待,下面可以参考,另外,
症状和解决方案-LATCH_XX
这意味着
存在非页闩锁
使用sys.dm_os_latch_stats来分析哪一个闩锁等待时间过长
和其它同时发生的等待类型结合查看
比如说CXPACKET和LATCH_EX与ACCESS_METHODs_SCAN_RANGE_GENERATOR往
往意味着存在大量扫描
症状和解决方案-LCK_M_XX
解决方案基于最开始被阻塞进程的等待类型
一个查范围更新或扫描造成的锁升级
症状和解决方案-
SOS_SCHEDULER_YIELD
这意味着
线程用完4毫秒的时间片,主动放弃CPU
存在自旋锁
不一定是CPU问题(CPU问题往往体现在长Runnable队列或大量signal wait)
通过执行计划查看是否存在大量扫描
查看等待类型
避免望文生义
更多分析
注意:该方式没有Resource_wait等待类型,因此一些查
另外关于sqltrace的,参考这个
另外你的服务器硬件配置还有数据库大小是什么样的?
建议你查询一下执行次数最多的sql和最耗费IO的sql,看看执行计划是不是缺少索引之类的
------解决思路----------------------
出现这种问题的原因,有2种:
1.硬件瓶颈。
就想你说的,加了内存后,好像又恢复正常了,一段时间又不行了,难道是因为数据量新增的速度远快于,你所加的内存量吗?
我觉得从长期来看,随着数据量的增加,确实会导致硬件的瓶颈,这个时候确实考虑要增加内存。
但是我觉得你这个问题,不是增加内存这么简单的。
2.需要优化sql语句。
sql server说白了,就是执行各种sql语句的一个程序,如果执行这些语句很慢,那么大部分的原因应该是你的sqli写的有问题,或者说你没有建立合理的索引。
所以,综合上面的2个,你现在要做的就是找到那些产生阻塞的sql语句,尝试优化这些语句。
如果你优化不了,那么可以贴出来,让大家帮你看看,如何优化