Fork me on GitHub

查询数据库死锁

 #查询CPU占用高的语句

SELECT TOP 10
   total_worker_time/execution_count AS avg_cpu_cost, plan_handle,
   execution_count,
   (SELECT SUBSTRING(text, statement_start_offset/2 + 1,
      (CASE WHEN statement_end_offset = -1
         THEN LEN(CONVERT(nvarchar(max), text)) * 2
         ELSE statement_end_offset
      END - statement_start_offset)/2)
   FROM sys.dm_exec_sql_text(sql_handle)) AS query_text
FROM sys.dm_exec_query_stats
ORDER BY [avg_cpu_cost] DESC 

 

#查询缺失索引
SELECT 
    DatabaseName = DB_NAME(database_id)
    ,[Number Indexes Missing] = count(*) 
FROM sys.dm_db_missing_index_details
GROUP BY DB_NAME(database_id)
ORDER BY 2 DESC;

SELECT  TOP 10 
        [Total Cost]  = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0) 
        , avg_user_impact
        , TableName = statement
        , [EqualityUsage] = equality_columns 
        , [InequalityUsage] = inequality_columns
        , [Include Cloumns] = included_columns
FROM        sys.dm_db_missing_index_groups g 
INNER JOIN    sys.dm_db_missing_index_group_stats s 
       ON s.group_handle = g.index_group_handle 
INNER JOIN    sys.dm_db_missing_index_details d 
       ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC;
 
#sql server性能分析--执行sql次数和逻辑次数,先以下命令清除sql server的缓存,dbcc freeProcCache 这个是最后一个
SELECT  creation_time  N'语句编译时间'

        ,last_execution_time  N'上次执行时间'

        ,total_physical_reads N'物理读取总次数'

        ,total_logical_reads/execution_count N'每次逻辑读次数'

        ,total_logical_reads  N'逻辑读取总次数'

        ,total_logical_writes N'逻辑写入总次数'

        , execution_count  N'执行次数'

        , total_worker_time/1000 N'所用的CPU总时间ms'

        , total_elapsed_time/1000  N'总花费时间ms'

        , (total_elapsed_time / execution_count)/1000  N'平均时间ms'

        ,SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,

         ((CASE statement_end_offset

          WHEN -1 THEN DATALENGTH(st.text)

          ELSE qs.statement_end_offset END

            - qs.statement_start_offset)/2) + 1) N'执行语句'

FROM sys.dm_exec_query_stats AS qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st

where SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,

         ((CASE statement_end_offset

          WHEN -1 THEN DATALENGTH(st.text)

          ELSE qs.statement_end_offset END

            - qs.statement_start_offset)/2) + 1) not like '%fetch%'

ORDER BY  total_elapsed_time / execution_count DESC;
#查看数据库死锁

生产环境:

View Code
USE [master]
GO
/****** Object:  StoredProcedure [dbo].[sp_who_lock]    Script Date: 05/03/2013 16:46:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[sp_who_lock]
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry     int,
@intRowcount             int,
@intCountProperties         int,
@intCounter             int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select  0 ,blocked
from (select * from sysprocesses where  blocked>0 ) a
where not exists(select * from (select * from sysprocesses
where  blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where  blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到临时表的记录数
select     @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if    @intCountProperties=0
select '现在没有阻塞和死锁信息' as message
-- 循环开始
while @intCounter <= @intCountProperties
begin
-- 取第一条记录
select     @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10))
+ '进程号,其执行的SQL语法如下'
else
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ ''
+ '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
DBCC INPUTBUFFER (@bl )
end
-- 循环指针下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end

=====================================================================================
USE [CRS]
GO
/****** Object:  StoredProcedure [dbo].[sp_who_lock2]    Script Date: 05/03/2013 16:47:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[sp_who_lock2]   
as      
begin      
   declare @spid int      
   declare @blk int      
   declare @count int      
   declare @index int      
   declare @lock tinyint       
   set @lock=0       
   create table #temp_who_lock       
 (       
  id int identity(1,1),       
  spid int,       
  blk int      
 )       
 create table #tmp_lock_mem
 (
    EventType varchar(30),
    Parameters varchar(10),
    EventInfo nvarchar(max)
 )
 if @@error<>0 return @@error       
 insert into #temp_who_lock(spid,blk)       
 select 0 ,blocked        
 from (select * from master..sysprocesses where blocked>0)a       
 where not exists(select * from  master..sysprocesses where a.blocked =spid and blocked>0)       
 union select spid,blocked from  master..sysprocesses where blocked>0       
 if @@error<>0 return @@error       
 select @count=count(*),@index=1 from #temp_who_lock       
 if @@error<>0 return @@error       
 if @count=0       
 begin      
  select '没有阻塞和死锁信息'      
  return 0       
 end      
 while @index<=@count       
 begin      
  if exists(select 1 from #temp_who_lock a where id>@index and exists(select 1 from #temp_who_lock where id<=@index and a.blk=spid))       
  begin      
   set @lock=1       
   select @spid=spid,@blk=blk from #temp_who_lock where id=@index      
   select '引起数据库死锁的是: '+ CAST(@spid AS VARCHAR(10)) + '进程号,其执行的SQL语法如下'      
   select  @spid, @blk     
   insert into CRS.dbo.sp_who_lock2LogForSPID select spid,blk,'引起数据库死锁的是: '+ CAST(@spid AS VARCHAR(10)) + '进程号,其执行的SQL语法如下',GETDATE()  from #temp_who_lock where id=@index  
   --dbcc inputbuffer(@spid)  
   delete  #tmp_lock_mem
   insert into #tmp_lock_mem exec('dbcc inputbuffer('+@spid+')')
   --insert into DBWareTest.dbo.sp_who_lock2Log exec('dbcc inputbuffer('+@spid+')')  
   insert into CRS.dbo.sp_who_lock2Log(EventType,Parameters,EventInfo) select * from #tmp_lock_mem       
   --dbcc inputbuffer(@blk)    
   delete  #tmp_lock_mem
   insert into #tmp_lock_mem exec('dbcc inputbuffer('+@blk+')') 
   --insert into DBWareTest.dbo.sp_who_lock2Log exec('dbcc inputbuffer('+@blk+')')     
   insert into CRS.dbo.sp_who_lock2Log(EventType,Parameters,EventInfo,createtime) select *,GETDATE() from #tmp_lock_mem  
  end      
  set @index=@index+1       
 end      
 if @lock=0        
 begin      
  set @index=1       
  while @index<=@count       
  begin      
   select @spid=spid,@blk=blk from #temp_who_lock where id=@index      
   if @spid=0   
   begin    
    select '引起阻塞的是:'+cast(@blk as varchar(10))+ '进程号,其执行的SQL语法如下'    
    insert into CRS.dbo.sp_who_lock2LogForSPID select spid,blk,'引起阻塞的是:'+cast(@blk as varchar(10))+ '进程号,其执行的SQL语法如下',GETDATE()  from #temp_who_lock where id=@index  
   end
   else    
    begin   
       select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '' + '进程号SPID:'+ CAST(@blk AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'      
       --dbcc inputbuffer(@spid)   
       delete  #tmp_lock_mem
       insert into #tmp_lock_mem exec('dbcc inputbuffer('+@spid+')')
       --insert into DBWareTest.dbo.sp_who_lock2Log exec('dbcc inputbuffer('+@spid+')')  
       insert into CRS.dbo.sp_who_lock2Log(EventType,Parameters,EventInfo,createtime) select *,GETDATE() from #tmp_lock_mem 
       insert into CRS.dbo.sp_who_lock2LogForSPID select spid,blk,'进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '' + '进程号SPID:'+ CAST(@blk AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下',GETDATE()  from #temp_who_lock where id=@index  
     end       
   --dbcc inputbuffer(@blk)  
   delete  #tmp_lock_mem
   insert into #tmp_lock_mem exec('dbcc inputbuffer('+@blk+')')     
   --insert into DBWareTest.dbo.sp_who_lock2Log exec('dbcc inputbuffer('+@blk+')')
   insert into CRS.dbo.sp_who_lock2Log(EventType,Parameters,EventInfo,createtime) select *,GETDATE() from #tmp_lock_mem 
   set @index=@index+1       
  end      
 end      
 drop table #temp_who_lock       
 return 0       
end            
  
  
  
  
        
  
  

测试环境:

CREATE procedure sp_who_lock  
as     
begin     
   declare @spid int     
   declare @blk int     
   declare @count int     
   declare @index int     
   declare @lock tinyint     
   set @lock=0     
   create table #temp_who_lock     
 (     
  id int identity(1,1),     
  spid int,     
  blk int     
 )     
 if @@error<>0 return @@error     
 insert into #temp_who_lock(spid,blk)     
 select 0 ,blocked      
 from (select * from master..sysprocesses where blocked>0)a     
 where not exists(select * from  master..sysprocesses where a.blocked =spid and blocked>0)     
 union select spid,blocked from  master..sysprocesses where blocked>0     
 if @@error<>0 return @@error     
 select @count=count(*),@index=1 from #temp_who_lock     
 if @@error<>0 return @@error     
 if @count=0     
 begin     
  select '没有阻塞和死锁信息'     
  return 0     
 end     
 while @index<=@count      
 begin     
  if exists(select 1 from #temp_who_lock a where id>@index and exists(select 1 from #temp_who_lock where id<=@index and a.blk=spid))     
  begin     
   set @lock=1     
   select @spid=spid,@blk=blk from #temp_who_lock where id=@index     
   select '引起数据库死锁的是: '+ CAST(@spid AS VARCHAR(10)) + '进程号,其执行的SQL语法如下'     
   select  @spid, @blk   
   dbcc inputbuffer(@spid)     
   dbcc inputbuffer(@blk)     
  end     
  set @index=@index+1     
 end     
 if @lock=0      
 begin     
  set @index=1     
  while @index<=@count      
  begin     
   select @spid=spid,@blk=blk from #temp_who_lock where id=@index     
   if @spid=0     
    select '引起阻塞的是:'+cast(@blk as varchar(10))+ '进程号,其执行的SQL语法如下'     
   else      
    select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '' + '进程号SPID:'+ CAST(@blk AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'     
   dbcc inputbuffer(@spid)   
   dbcc inputbuffer(@blk)     
   set @index=@index+1     
  end     
 end     
 drop table #temp_who_lock     
 return 0     
end           
GO
posted @ 2013-04-30 21:39  花儿笑弯了腰  阅读(520)  评论(0编辑  收藏  举报