当前位置: 代码迷 >> Sql Server >> [],SQL SERVER 有一个数据表老被阻塞,一句Update都要200秒
  详细解决方案

[],SQL SERVER 有一个数据表老被阻塞,一句Update都要200秒

热度:90   发布时间:2016-04-24 09:46:09.0
[求助],SQL SERVER 有一个数据表老被阻塞,一句Update都要200秒,
SQL SERVER 2008 有一个数据表老被阻塞,一句对主键定位的Update都要200秒.
要如何去查到是哪句语句阻塞了这个表? 
------解决思路----------------------
黄版主发过不少监控的脚本,我个人也收集了一些
SELECT wt.blocking_session_id AS BlockingSessesionId,
       sp.program_name AS ProgramName,
       COALESCE(sp.LOGINAME, sp.nt_username) AS HostName,
       ec1.client_net_address AS ClientIpAddress,
       db.name AS DatabaseName,
       wt.wait_type AS WaitType,
       ec1.connect_time AS BlockingStartTime,
       wt.WAIT_DURATION_MS / 1000 AS WaitDuration,
       ec1.session_id AS BlockedSessionId,
       h1.TEXT AS BlockedSQLText,
       h2.TEXT AS BlockingSQLText
  FROM sys.dm_tran_locks AS tl
 INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
 INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address =
                                             wt.resource_address
 INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id =
                                           tl.request_session_id
 INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id =
                                           wt.blocking_session_id
  LEFT OUTER JOIN master.dbo.sysprocesses sp ON SP.spid =
                                                wt.blocking_session_id
 CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
 CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2

------解决思路----------------------

/*
exec p_lockinfo  1,0
--*/  
create proc p_lockinfo  
@kill_lock_spid bit=1,  --是否杀掉死锁的进程,1 杀掉, 0 仅显示  
@show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示  
as  
declare @count int,@s nvarchar(1000),@i int  
select id=identity(int,1,1),标志,  
 进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,  
 数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,  
 登陆时间=login_time,打开事务数=open_tran, 进程状态=status,  
 工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,  
 域名=nt_domain,网卡地址=net_address  
into #t from(  
 select 标志='死锁的进程',  
  spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,  
  status,hostname,program_name,hostprocess,nt_domain,net_address,  
  s1=a.spid,s2=0  
 from master..sysprocesses a join (  
  select blocked from master..sysprocesses group by blocked  
  )b on a.spid=b.blocked where a.blocked=0  
 union all  
 select '
------解决思路----------------------
_牺牲品_>',  
  spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,  
  status,hostname,program_name,hostprocess,nt_domain,net_address,  
  s1=blocked,s2=1  
 from master..sysprocesses a where blocked<>0  
)a order by s1,s2  
  
select @count=@@rowcount,@i=1  
  
if @count=0 and @show_spid_if_nolock=1  
begin  
 insert #t  
 select 标志='正常的进程',  
  spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,  
  open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address  
 from master..sysprocesses  
 set @count=@@rowcount  
end  
  
if @count>0  
begin  
 create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))  
 if @kill_lock_spid=1  
 begin  
  declare @spid varchar(10),@标志 varchar(10)  
  while @i<=@count  
  begin  
   select @spid=进程ID,@标志=标志 from #t where id=@i  
   insert #t1 exec('dbcc inputbuffer('+@spid+')')  
   if @标志='死锁的进程' exec('kill '+@spid)  
   set @i=@i+1  
  end  
 end  
 else  
  while @i<=@count  
  begin  
   select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i  
   insert #t1 exec(@s)  
   set @i=@i+1  
  end  
 select a.*,进程的SQL语句=b.EventInfo  
 from #t a join #t1 b on a.id=b.id  
end  
go  

begin tran    exec 
sp_helptext p_test_hy   select * from #f_sale_vendor   rollback


抄的一个,很好用的!
------解决思路----------------------
select   request_session_id   spid,OBJECT_NAME(resource_associated_entity_id) tableName   
from   sys.dm_tran_locks where resource_type='OBJECT'
 
spid   锁表进程 
tableName   被锁表名
 
解锁:
 
declare @spid  int 
Set @spid  = 57 --锁表进程
declare @sql varchar(1000)
set @sql='kill '+cast(@spid  as varchar)
exec(@sql)
看下不知道有没有用~~
------解决思路----------------------
一些平时0秒的查询语句(带了 WIth (nolock) 参数的)也超过200秒.

是不是有数据库文件的自动增长所致?
  相关解决方案