zoukankan      html  css  js  c++  java
  • SQL 维护用得到的监控语句

    使用DMV来分析SQL Server启动以来累计使用CPU资源最多的语句。例如下面的语句就可以列出前50名

    SELECT TOP 50 s2.dbid, 
        (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 sql_statement,
        execution_count,     plan_generation_num,     last_execution_time,       total_worker_time,     
    
    last_worker_time,     min_worker_time, 
        max_worker_time,    total_physical_reads,     last_physical_reads, 
        min_physical_reads,      max_physical_reads,      total_logical_writes,     last_logical_writes,     
    
    min_logical_writes,     max_logical_writes
    FROM sys.dm_exec_query_stats AS s1 
    CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2  
    WHERE s2.objectid is null
    ORDER BY s1.total_worker_time desc
    
    --第二种
    select  c.last_execution_time,c.execution_count,c.total_logical_reads,
    c.total_logical_writes,c.total_elapsed_time,c.last_elapsed_time,q.[text]
    from  (select top 50 qs.*    from sys.dm_exec_query_stats qs    
    order by qs.total_worker_time desc) as c    
    cross apply sys.dm_exec_sql_text(plan_handle) 
    as q order by c.total_worker_time desc 

    返回最经常运行的100条语句

    SELECT TOP 100 cp.cacheobjtype,cp.usecounts,cp.size_in_bytes,
    qs.statement_start_offset,qs.statement_end_offset,qt.dbid 
    ,qt.objectid  
    ,SUBSTRING(qt.text,qs.statement_start_offset/2, 
      (case when qs.statement_end_offset = -1 
       then len(convert(nvarchar(max), qt.text)) * 2  
        else qs.statement_end_offset end -qs.statement_start_offset)/2) 
        as statement FROM sys.dm_exec_query_stats qs 
        cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt 
        inner join sys.dm_exec_cached_plans as cp on qs.plan_handle=cp.plan_handle 
        where cp.plan_handle=qs.plan_handle and cp.usecounts>4 
        ORDER BY [dbid],[Usecounts] DESC

    返回做IO数目最多的50条语句以及它们的执行计划

    select top 50 (total_logical_reads/execution_count) as avg_logical_reads,
    (total_logical_writes/execution_count) as avg_logical_writes,
    (total_physical_reads/execution_count) as avg_phys_reads,
    Execution_count, 
    statement_start_offset as stmt_start_offset, 
    statement_end_offset as stmt_end_offset,
    substring(sql_text.text, (statement_start_offset/2), 
    case when (statement_end_offset -statement_start_offset)/2 <=0 then 64000 
    else (statement_end_offset -statement_start_offset)/2 end) as exec_statement, 
     sql_text.text,plan_text.* 
     from sys.dm_exec_query_stats  
     cross apply sys.dm_exec_sql_text(sql_handle) as sql_text
     cross apply sys.dm_exec_query_plan(plan_handle) as plan_text
     order by  (total_logical_reads + total_logical_writes) /Execution_count Desc

    计算signal wait占整wait时间的百分比
    指令等待 CPU 资源的时间占总时间的百分比。如果超过 25% ,说明 CPU 紧张

    select convert(numeric(5,4),sum(signal_wait_time_ms)/sum(wait_time_ms)) 
    from Sys.dm_os_wait_stats 

    计算'Cxpacket'占整wait时间的百分比
    Cxpacket:Sql Server 在处理一句代价很大的语句,要不就是没有合适的索引或筛选条件没能筛选足够的记录,使得
    语句要返回大量的结果,当 >5% 说明有问题

    declare @Cxpacket bigint
    declare @Sumwaits bigint
    select @Cxpacket = wait_time_ms
    from Sys.dm_os_wait_stats
    where wait_type = 'Cxpacket'
    select @Sumwaits = sum(wait_time_ms)
    from Sys.dm_os_wait_stats
    select convert(numeric(5,4),@Cxpacket/@Sumwaits)

    查询当前数据库上所有用户表格在Row lock上发生阻塞的频率

    declare @dbid int
    select @dbid = db_id()
    Select dbid=database_id, objectname=object_name(s.object_id), 
    indexname=i.name, i.index_id    
    --, partition_number, row_lock_count, 
    row_lock_wait_count, [block %]=cast (100.0 * row_lock_wait_count / (1 + row_lock_count) 
    as numeric(15,2)), row_lock_wait_in_ms, 
    [avg row lock waits in ms]=cast (1.0 * row_lock_wait_in_ms / (1 + row_lock_wait_count) 
    as numeric(15,2))
    from sys.dm_db_index_operational_stats (@dbid, NULL, NULL, NULL) s,  
       sys.indexes i where objectproperty(s.object_id,'IsUserTable') = 1
       and i.object_id = s.object_id and i.index_id = s.index_id
       order 
       by row_lock_wait_count desc

    返回当前数据库所有碎片率大于25%的索引
    运行本语句会扫描很多数据页面
    避免在系统负载比较高时运行
    避免在系统负载比较高时运行

    declare @dbid int
    select @dbid = db_id()
    SELECT o.name as tablename,s.* 
    FROM sys.dm_db_index_physical_stats (@dbid, NULL, NULL, NULL, NULL) s,
    sys.objects o
    where avg_fragmentation_in_percent>25 and o.object_id =s.object_id
    order by avg_fragmentation_in_percent desc

    当前数据库可能缺少的索引

    select d.*        , s.avg_total_user_cost        , 
    s.avg_user_impact        , s.last_user_seek        ,
    s.unique_compiles
    from sys.dm_db_missing_index_group_stats s        ,
    sys.dm_db_missing_index_groups g        ,
    sys.dm_db_missing_index_details d
    where s.group_handle = g.index_group_handle
    and d.index_handle = g.index_handle
    order by s.avg_user_impact desc

    自动重建或重新组织索引

    SET NOCOUNT ON;DECLARE @objectid int;DECLARE @indexid int;DECLARE @partitioncount bigint;
    DECLARE @schemaname nvarchar(130); DECLARE @objectname nvarchar(130); 
    DECLARE @indexname nvarchar(130); DECLARE @partitionnum bigint;
    DECLARE @partitions bigint;DECLARE @frag float;DECLARE @command nvarchar(4000); 
    -- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function 
    -- and convert object and index IDs to names.
    SELECT    object_id AS objectid,    index_id AS indexid,    partition_number AS partitionnum,    
    
    avg_fragmentation_in_percent AS frag
    INTO 
    #work_to_do
    FROM sys.dm_db_index_physical_stats (DB_ID(),
     NULL, NULL , NULL, 'LIMITED')
     WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;
     -- Declare the cursor for the list of partitions to be processed.
     DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;
     -- Open the cursor.
     OPEN partitions;
     -- Loop through the partitions.
     WHILE (1=1)    
     BEGIN;        FETCH NEXT           FROM partitions          
      INTO @objectid, @indexid, @partitionnum, @frag;    
          IF @@FETCH_STATUS < 0 BREAK;       
           SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)   
                FROM sys.objects AS o        JOIN sys.schemas as s ON s.schema_id = o.schema_id       
                 WHERE o.object_id = @objectid;       
                  SELECT @indexname = QUOTENAME(name)     
                     FROM sys.indexes      
                       WHERE  object_id = @objectid AND index_id = @indexid;     
                          SELECT @partitioncount = count (*)        FROM sys.partitions  
                                WHERE object_id = @objectid AND index_id = @indexid;
                                -- 30 is an arbitrary decision point at which to switch between reorganizing 
    
    and rebuilding.     
                                   IF @frag < 30.0          
                                     SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + 
    
    N'.' + @objectname + N' REORGANIZE';        
                                     IF @frag >= 30.0          
                                       SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + 
    
    N'.' + @objectname + N' REBUILD';       
                                        IF @partitioncount > 1      
                                              SET @command = @command + N' PARTITION=' + CAST(@partitionnum 
    
    AS nvarchar(10));    
                                                  EXEC (@command);       
                                                   PRINT N'Executed: ' + @command;    END;
                                                   -- Close and deallocate the cursor.
                                                   CLOSE partitions;
                                                   DEALLOCATE partitions;
                                                   -- Drop the temporary table.
                                                   DROP TABLE #work_to_do;

    查看当前数据库索引的使用率

    SELECT
    object_name(object_id) as table_name,
    (select name from sys.indexes
    where object_id = stats.object_id 
    and index_id = stats.index_id) 
    as index_name,*
    FROM sys.dm_db_index_usage_stats 
    as stats
    WHERE database_id = DB_ID()order by table_name

    指定表的索引使用情况

    declare @table as nvarchar(100)
    set @table = 'Table_1';
    SELECT(  select name  from sys.indexes  
    where object_id = stats.object_id and index_id = stats.index_id) 
    as index_name,*
    FROM sys.dm_db_index_usage_stats as stats
    where object_id = object_id(@table)
    order by user_seeks, user_scans, user_lookups asc

    最经常做重编译的存储过程

    select top 25 sql_text.text, sql_handle, plan_generation_num,  execution_count,
    
        dbid,  objectid 
    
    from sys.dm_exec_query_stats a
    
        cross apply sys.dm_exec_sql_text(sql_handle) as sql_text
    
    where plan_generation_num>1
    
    order by plan_generation_num desc

    sp_lock 
    select OBJECT_NAME(objid)
    dbcc inputbuffer(spid) 
    select @@spid
    kill 58 WITH STATUSONLY
    EXEC sp_who 'active'

    查询系统中死锁的SQL语句

    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 print @@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 print @@ERROR
    -- 找到临时表的记录数
    select     @intCountProperties = Count(*),@intCounter = 1
    from #tmp_lock_who
    IF @@ERROR<>0 print @@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
    
    select * from #tmp_lock_who
    
    drop table #tmp_lock_who
    
    select @@lock_timeout

    查看锁信息

     select   进程id=req_spid   
      ,数据库=db_name(rsc_dbid)   
      ,类型=case   rsc_type   when   1   then   'NULL   资源(未使用)'   
      when   2   then   '数据库'   
      when   3   then   '文件'   
      when   4   then   '索引'   
      when   5   then   ''   
      when   6   then   ''   
      when   7   then   ''   
      when   8   then   '扩展盘区'   
      when   9   then   'RID(行   ID)'   
      when   10   then   '应用程序'   
      end   
      ,rsc_objid,rsc_indid   
      from   master..syslockinfo   
    
    
    
    select * from sys.dm_tran_locks
    SET SHOWPLAN_ALL ON; SET STATISTICS IO on; SET STATISTICS TIME on

    列出最初锁住资源,导致一连串其他进程被锁住的起始源头

    IF EXISTS(SELECT * FROM master.sys.sysprocesses WHERE spid 
        IN (SELECT blocked FROM master.sys.sysprocesses))    
        --确定有进程被其他的进程锁住
        SELECT 
             DISTINCT '进程ID' = STR(a.spid, 4)
            ,'进程ID状态' = CONVERT(CHAR(10), a.status)
            ,'登入帐号'=SUBSTRING(SUSER_SNAME(sid),1,30) 
            ,'工作站名称' = CONVERT(CHAR(10), a.hostname)
            ,'执行命令的用户' = CONVERT(CHAR(10), SUSER_NAME(a.uid))
            ,'是否被锁住'=CONVERT(char(3),blocked)
            ,'数据库名' = CONVERT(CHAR(10), DB_NAME(a.dbid))
            ,'正在执行的命令' = CONVERT(CHAR(16), a.cmd)
            ,'登录名' = a.loginame
            ,'执行语句' = b.text
            ,'等待型态' = a.waittype  
        FROM master..sysprocesses a CROSS APPLY sys.dm_exec_sql_text(a.sql_handle) b 
        --列出锁住别人(在别的进程中 blocked字段出现的值),但自己未被锁住(blocked=0)
        WHERE spid IN (SELECT blocked FROM master.sys.sysprocesses) 
        AND blocked=0
    ELSE
        SELECT 'No Blocked Session(s)'
    --a.status = suspended,a.blocked(阻塞者id)
    --DBCC INPUTBUFFER (阻塞者id);
    --就可以看到语句了或者join

    经常出现的是,在sysprocesses视图中 status是'sleeping',waittype字段是0x0000,打开事务数open_tran大于0,一般
    都是交易已经激活但迟迟没有结束,就可能是程序没有管理好交易管理

    select a.*,b.text
    from master.sys.sysprocesses a  
    CROSS APPLY sys.dm_exec_sql_text(a.sql_handle) b
    where a.status = 'sleeping' and a.waittype=0x0000 and a.open_tran > 0
    
    
    select t1.resource_type as [资源锁定类型]
        ,db_name(resource_database_id) as [数据库名]
        ,t1.resource_associated_entity_id as [锁定的对象]
        ,t1.request_mode as [等待者需求的锁定类型]
        ,t1.request_session_id as [等待者sid]  
        ,t2.wait_duration_ms as [等待时间]    
        ,(select text from sys.dm_exec_requests as r  
            cross apply sys.dm_exec_sql_text(r.sql_handle) 
            where r.session_id = t1.request_session_id) as [等待者要执行的批次]
        ,(select substring(qt.text,r.statement_start_offset/2+1, 
                (case when r.statement_end_offset = -1 
                then datalength(qt.text) 
                else r.statement_end_offset end - r.statement_start_offset)/2+1) 
            from sys.dm_exec_requests as r
            cross apply sys.dm_exec_sql_text(r.sql_handle) as qt
            where r.session_id = t1.request_session_id) as [等待者正要执行的语法]
         ,t2.blocking_session_id as [锁定者sid] 
         ,(select text from sys.sysprocesses as p        
            cross apply sys.dm_exec_sql_text(p.sql_handle) 
            where p.spid = t2.blocking_session_id) as [锁定者的语法]
        from 
        sys.dm_tran_locks as t1, 
        sys.dm_os_waiting_tasks as t2
    where 
        t1.lock_owner_address = t2.resource_address

    统计分析

    DBCC SHOW_STATISTICS('表名','索引名')
  • 相关阅读:
    加州大学Santa Barbara量化课程
    专利分析与申请(2):SILK 专利的特点
    两种可分级语音编码器的量化器
    芬兰赫尔辛基工业大学DirAC工程:Directional audio coding
    SILK 的 Delay Decision 和 Dither
    Fraunhofer 研究院
    ICASSP 论文发表相关问题
    SILK 学习总结之位分配与低码率编码
    今天测试VOIP软件结果
    国内部分音频语音相关研究企业(实时更新)
  • 原文地址:https://www.cnblogs.com/StupidsCat/p/3183923.html
Copyright © 2011-2022 走看看