生产环境中都会定期做release,release完成后有时候数据库服务器会出现CPU和内存飙升的现象,需要有监控机制监控。
当这个问题出现的时候,大多数都是因为release时候有数据上的很大变动,统计信息并没有更新,导致缓存的执行计划出现很大的偏差,性能极具下降,尤其是那种每分钟多次调用的存储过程。
这种情况下,只需要重新编译一下这个存储过程,使之生成新的正确的执行计划即可。
如何迅速定位是哪个存储过程出现的问题,下面的方法快捷方便:
第一步: 查出正在跑的存储过程,找到耗时长的spid, 多记录几个spid,大部分情况是,虽然spid不同,但是调用的存储过程却是同一个
select p.session_id, p.request_id, p.start_time,percent_complete,
p.status, p.command, p.blocking_session_id, p.wait_type, p.wait_time,
p.wait_resource, p.total_elapsed_time as [total_elapsed_time_milliseconds],
(p.total_elapsed_time/1000)/60 as [total_elapsed_time_minutes], p.open_transaction_count,
p.transaction_isolation_level,
substring(qt.text, p.statement_start_offset /2,
(case when p.statement_end_offset = -1 then len(convert(nvarchar(max),qt.text) )* 2
else p.statement_end_offset end - p.statement_start_offset) / 2 ) as sqlstatement,
p.statement_start_offset, p.statement_end_offset, batch=qt.text
from master.sys.dm_exec_requests p
cross apply sys.dm_exec_sql_text(p.sql_handle) as qt
where p.session_id>50
第二步: 用DBCC 命令,定位存储过程
dbcc inputbuffer(spid)
第三步: 重新编译此存储过程
sp_recompile spname
搞定!