根据在固态查询优化方面的经验,I/O等待是目前客户遇到的最常见等待。这其中有几个原因,I/O通常是数据处理操作最昂贵的资源。而且,当对查询或索引的设计或优化的不理想的情况下,会导致额外的I/O。此时,客户考虑计算机性能是,一般只考虑cpu和内存,而不会给I/O子系统足够的关注,数据库系统需要强健的I/O子系统。
有些系统不必访问大部分数据,只对少数数据频繁访问。使用OLTP时通常是这种情况,它包含存储过程和查询只访问少量数据,但是调用频繁。在这种情况下,代码的编译和重新编译可能成为产生瓶颈的主要原因。OLTP系统涉及大量对少量数据的频繁修改,在这种情况下事务日志经常成为瓶颈。因为所有临时表的创建都是tempdb数据库中创建(无论是执行计划显式或者隐式创建),tempdb数据库可能成为非常严重的瓶颈。SQL Server经常使用tempdb执行其他操作。我们偶尔也发现存在并发及其其他问题。
但是当我们根据SQL提供的等待信息内容太多,通过手动找出最关键的等待不是很方便。根据2-8原则,通常少量的等待占据了大部分等待时间。
1:如下查询出累计值达到系统等待时间80%的重量级等待。
1 --date:2013-5-13 2 --DESC:sys.dm_os_wait_stats中,wait_time_ms表示所有进程在等待类型上的总等待时间, 3 -- 即使多个进程同时等待也计算在内。尽管如此,这些数字还是通常可以找到系统的主要问题域 4 with waits 5 as 6 ( 7 select 8 t.wait_type, 9 t.wait_time_ms/1000 as wait_time_s, 10 100* t.wait_time_ms/SUM(t.wait_time_ms) over() as pct, 11 ROW_NUMBER() over(order by t.wait_time_ms desc) rn 12 from 13 sys.dm_os_wait_stats t 14 where t.wait_type not like '%SLEEP%' --过滤掉不相关的等待 15 ) 16 select 17 t.wait_type, 18 CAST(t.wait_time_s as decimal(12,2)) as wait_time_s, 19 CAST(t.pct as decimal(12,2)) as pct, 20 CAST(SUM(t1.pct) as decimal(12,2)) as running_pct 21 from 22 waits t 23 inner join waits t1 on t1.rn<=t.rn 24 group by t.rn,t.wait_type,t.wait_time_s,t.pct 25 having SUM(t1.pct)-t.pct<80 --百分比临界值 26 order by t.rn
2:将保存的信息保存到临时表中,进行分析。定时更新(例如每一个小时一次)。这样可以分析中一天等待的分布,找出高峰值。
1 --DESC:创建表结构 2 use databaseName 3 go 4 5 if OBJECT_ID('WaitStats') is not null 6 drop table waitStats; 7 go 8 9 select 10 GETDATE() as dt, 11 t.wait_type, 12 t.waiting_tasks_count, 13 t.wait_time_ms, 14 t.max_wait_time_ms, 15 t.signal_wait_time_ms 16 17 into waitStats 18 from 19 sys.dm_os_wait_stats t 20 where 1=2 --创建框架
定时插入数据到状态表中。提醒wait_time_ms是累计值
1 --DESC:定时插入数据到状态表中 2 insert into waitStats 3 select 4 GETDATE() as dt, 5 t.wait_type, 6 t.waiting_tasks_count, 7 t.wait_time_ms, 8 t.max_wait_time_ms, 9 t.signal_wait_time_ms 10 from 11 sys.dm_os_wait_stats t;
根据时间段条件,查询出此时间段内等待类型,等待时间。提供dba分析系统资料
1 if OBJECT_ID('fn_inteval_waits') is not null 2 drop function fn_inteval_waits 3 go 4 --date:2013-5-14 5 --DESC:根据开始时间和截止时间查询等待类型等待你时间的长度 6 create function fn_inteval_waits 7 (@fromdt datetime,@todt datetime) 8 returns table 9 as 10 return 11 with Waits as 12 ( 13 select 14 dt,wait_type,wait_time_ms, 15 row_number() over (partition by wait_type order by dt)as rn 16 from 17 WaitStats w 18 where dt>=@fromdt and dt<@todt+1 19 ) 20 select prv.wait_type,prv.dt as starttime, 21 CAST((cur.wait_time_ms-prv.wait_time_ms)/1000 as decimal(12,2)) as interval_wait_s 22 from 23 Waits as cur 24 inner join Waits prv 25 on cur.wait_type=prv.wait_type and cur.rn=prv.rn+1 26 and prv.dt<=@todt 27 go 28 29 30 select t.wait_type,t.starttime,t.interval_wait_s 31 from 32 fn_inteval_waits('2013-5-13','2013-5-15') as t 33 order by sum(interval_wait_s) over (partition by wait_type) desc, 34 t.wait_type,t.starttime
家家有老人
人人会变老
帮老就是帮未来的您