zoukankan      html  css  js  c++  java
  • MS SQL 日常维护管理常用脚本(二)

    监控数据库运行

    下面是整理、收集监控数据库运行的一些常用脚本,也是MS SQL 日常维护管理常用脚本(一)的续集,欢迎大家补充、提意见。

    查看数据库登录名信息
     
    Code Snippet
    1. SELECT name                                AS LoginName ,
    2.        dbname                              AS DefaultDB ,
    3.        createdate                          AS CreateDate,
    4.        updatedate                          AS UpdateDate,
    5.        language                            AS Language  ,
    6.        CASE WHEN isntname = 1 THEN 'NT USER'
    7.            ELSE 'SQL USER'    END          AS UserType
    8. FROM syslogins;
    查看数据库用户信息
     
    SELECT * FROM sysusers;
     
    查看用户拥有的服务器角色
     

    方法1: 用SSMS管理工具查看


    方法2: 脚本查询

     
    查看用户角色
    1. SELECT name            ,
    2.        CASE WHEN sysadmin     = 1       THEN 'yes'     ELSE '' END AS IsSysadmin        ,
    3.        CASE WHEN dbcreator    = 1       THEN 'yes'     ELSE '' END AS IsDbCreate        ,
    4.        CASE WHEN securityadmin= 1       THEN 'yes'     ELSE '' END AS IsSecurityadmin   ,
    5.        CASE WHEN bulkadmin    = 1       THEN 'yes'     ELSE '' END AS IsBulkadmin       ,
    6.        CASE WHEN diskadmin    = 1       THEN 'yes'     ELSE '' END AS IsDiskadmin       ,
    7.        CASE WHEN processadmin = 1       THEN 'yes'     ELSE '' END AS IsProcessadmin    ,
    8.        CASE WHEN serveradmin  = 1       THEN 'yes'     ELSE '' END AS IsServeradmin     ,
    9.        CASE WHEN setupadmin   = 1       THEN 'yes'     ELSE '' END AS IsSetupadmin    
    10. FROM syslogins
    11. --WHERE NAME='loginname'
     
    查看最大工作线程数
     
    Code Snippet
    1. SELECT  max_workers_count
    2.   FROM  sys.dm_os_sys_info

    查看当前用户进程的会话ID

    SELECT @@SPID

    查询当前会话使用哪种协议

    Code Snippet
    1. SELECT net_transport
    2. FROM   sys.dm_exec_connections
    3. WHERE session_id = @@SPID;
     
    查看当前连接的会话信息

    --进程号1--50是SQL Server系统内部用的
    SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51
     
    --查看某台机器的连接会话信息
    SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51 AND host_name='PO130018801'
     
    --查看某个登录名的连接会话信息
    SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51 AND login_name='username'
     
    --查看活动的连接会话信息
    SELECT * FROM sys.dm_exec_sessions WITH(NOWAIT) WHERE session_id >=51 AND status ='running'
     
    --查找连接到服务器的用户并返回每个用户的会话数
    SELECT  login_name ,
            COUNT(session_id) AS session_count
    FROM    sys.dm_exec_sessions
    GROUP BY login_name ;
     
     
    查看正在执行的SQL语句
     

    方法1: 选择数据库实例,单击右键,选择”活动监视器“,监控/查看正在执行的SQL


    方法2: profile去跟踪,比较耗费资源。

    方法3:

     
    Code Snippet
    1. SELECT[Spid] = session_Id ,
    2.       ecid ,
    3.       [Database] = DB_NAME(sp.dbid) ,
    4.       [User] = nt_username ,
    5.       [Status] = er.status ,
    6.       [Wait] = wait_type ,
    7.       [Individual Query] = SUBSTRING(qt.text, er.statement_start_offset / 2,
    8.                                      ( CASE WHEN er.statement_end_offset = -1
    9.                                             THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))
    10.                                                  * 2
    11.                                             ELSE er.statement_end_offset
    12.                                        END - er.statement_start_offset ) / 2) ,
    13.       [Parent Query] = qt.text ,
    14.       Program = program_name ,
    15.       Hostname ,
    16.       nt_domain ,
    17.       start_time
    18.   FROMsys.dm_exec_requests er
    19.       INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
    20.       CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
    21.  WHEREsession_Id >= 51

    方法4:

    Code Snippet
    1. SELECT   m.session_id ,
    2.          m.start_time ,
    3.          m.command    ,
    4.          m.wait_type  ,
    5.          m.cpu_time   ,
    6.         CAST(s.text AS VARCHAR(1000)) AS sqlText
    7.  FROMmaster.sys.dm_exec_requests m WITH ( NOLOCK )
    8.      CROSS APPLY fn_get_sql(m.sql_handle) s
    9.  
    10. SELECT  r.session_id,
    11.         r.start_time      ,
    12.         r.command         ,
    13.         r.wait_type       ,
    14.         r.cpu_time        ,
    15.         s.text  
    16.  FROMsys.dm_exec_requests r
    17.      CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s

    --查看某个会话ID正在执行的SQL

    Code Snippet
    1. SELECT  m.session_id ,
    2.         m.start_time ,
    3.         m.command    ,
    4.         m.wait_type  ,
    5.         m.cpu_time   ,
    6.       CAST(s.text AS VARCHAR(1000)) AS sqlText
    7.   FROMmaster.sys.dm_exec_requests m WITH ( NOLOCK )
    8.       CROSS APPLY fn_get_sql(m.sql_handle) s
    9.  WHEREm.session_id = 342
    10.  
    11.     SELECT   r.session_id      ,
    12.              r.start_time      ,
    13.              r.command         ,
    14.              r.wait_type       ,
    15.              r.cpu_time        ,
    16.              s.text  
    17.   FROM sys.dm_exec_requests r
    18.       CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
    19. WHERE r.seesion_id =342

    查看SQL SERVER进程执行的语句

    Code Snippet
    1. USE master
    2.  
    3. DECLARE @spid INT ;
    4.  
    5. DECLARE @sql_handle BINARY(20) ;
    6.  
    7. SET @spid = 56
    8.  
    9.   SELECT@sql_handle = sql_handle
    10.     FROMsysprocesses AS A WITH ( NOLOCK )
    11.    WHEREspid = @spid ;
    12.  
    13.   SELECTtext
    14.     FROM::fn_get_sql(@sql_handle) ;
     
    查找TOP N语句

    按平均 CPU 时间返回排名前十个的查询的相关信息。此示例将根据查询的查询哈希对查询进行聚合,以便按照查询的累积资源消耗来分组在逻辑上等效的查询。
    --注意:SQL 2005 某些版本,没有sys.dm_exec_query_stats系统动态视图没有query_hash视图。

    Code Snippet
    1. USE DBNAME;
    2. GO
    3. SELECT TOP 10 query_stats.query_hash             AS "Query Hash",
    4.     SUM(query_stats.total_worker_time) /
    5.     SUM(query_stats.execution_count)             AS "Avg CPU Time",
    6.     MIN(query_stats.statement_text)              AS "Statement Text"
    7. FROM
    8.     (SELECT QS.*,
    9.     SUBSTRING(ST.text,(QS.statement_start_offset/2) + 1,
    10.     ((CASE statement_end_offset
    11.         WHEN -1 THEN DATALENGTH(st.text)
    12.         ELSE QS.statement_end_offset END
    13.             - QS.statement_start_offset)/2) + 1) AS statement_text
    14.      FROM sys.dm_exec_query_stats AS QS
    15.      CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
    16. GROUP BY query_stats.query_hash
    17. ORDER BY 2 DESC;
    18. GO
    查看会话阻塞/死锁信息
     

    方法1:查看那个引起阻塞,查看blk不为0的记录,如果存在阻塞进程,则是该阻塞进程的会话 ID。否则该列为零。 

        EXEC sp_who active

    方法2:查看那个引起阻塞,查看字段BlkBy,这个能够得到比sp_who更多的信息。

        EXEC sp_who2 active

    方法3:sp_lock 系统存储过程,报告有关锁的信息,但是不方便定位问题


    方法4:sp_who_lock存储过程

    Code Snippet
    1. USE master;
    2. GO
    3.  
    4. SET ANSI_NULLS ON;
    5. GO
    6.  
    7. SET QUOTED_IDENTIFIER ON;
    8. GO
    9.  
    10. IF EXISTS(SELECT 1 FROM sysobjects WHERE id=OBJECT_ID(N'sp_who_lock')
    11.                                        AND OBJECTPROPERTY(id, 'IsProcedure') =1)
    12.     DROP PROCEDURE sp_who_lock;
    13. GO
    14.  
    15. --==================================================================================================
    16. --            ProcedureName             :            sp_who_lock
    17. --            Author                    :            作者不详,出自网络
    18. --            CreateDate                :            2013-05-13
    19. --            Description               :            查看阻塞和死锁信息
    20. /**************************************************************************************************
    21.         Parameters                    :              参数说明
    22. ***************************************************************************************************
    23.                                                      无参存储过程
    24. ***************************************************************************************************
    25.         Modified Date            Modified User     Version                 Modified Reason
    26. ***************************************************************************************************
    27.        2013-06-03                    Kerry        V01.00.01 调整存储过程格式,代码部分修改以及增加注释信息
    28. ***************************************************************************************************/
    29. --=================================================================================================
    30.  
    31.   CREATE PROCEDURE sp_who_lock
    32.     AS
    33. BEGIN
    34.  
    35. DECLARE @spid                            INT;
    36. DECLARE @block                           INT;
    37. DECLARE @RowCount                        INT;
    38. DECLARE @RowIndex                        INT;
    39.  
    40. --创建临时表,保持被阻塞或正阻塞其他SQL的SQL语句信息
    41. CREATE TABLE #tmp_lock_who
    42. (
    43.       id    INT IDENTITY(1, 1) ,
    44.       spid    SMALLINT ,
    45.       block SMALLINT
    46. )
    47.     
    48.     
    49. IF @@ERROR<>0 RETURN @@ERROR;
    50.  
    51. INSERT INTO #tmp_lock_who
    52.         (
    53.           spid ,
    54.           block
    55.         )
    56.         SELECT  0 ,
    57.                 blocked
    58.         FROM    ( SELECT    *
    59.                   FROM      sysprocesses
    60.                   WHERE     blocked > 0
    61.                 ) a
    62.         WHERE   NOT EXISTS( SELECT *
    63.                              FROM   ( SELECT    *
    64.                                       FROM      sysprocesses
    65.                                       WHERE     blocked > 0
    66.                                     ) b
    67.                              WHERE  a.blocked = spid )
    68.         UNION
    69.         SELECT  spid ,
    70.                 blocked
    71.         FROM    sysprocesses
    72.         WHERE   blocked > 0;
    73.         
    74.         
    75. IF @@ERROR<>0 RETURN @@ERROR;
    76.  
    77.  
    78. -- 找到临时表的记录数
    79.   SELECT@RowCount = COUNT(1) ,
    80.         @RowIndex = 1
    81.     FROM#tmp_lock_who
    82.  
    83.  
    84. IF @@ERROR<>0 RETURN @@ERROR;
    85.  
    86.   IF@RowCount=0
    87.   SELECT  N'现在没有阻塞和死锁信息' AS MESSAGE;
    88.  
    89.  
    90. -- -- 循环开始
    91. WHILE @RowIndex <= @RowCount
    92. BEGIN
    93.     -- 取第一条记录
    94.     SELECT     @spid    = spid,
    95.                @block   = block
    96.     FROM #tmp_lock_who
    97.     WHERE Id = @RowIndex
    98.  
    99.     IF @spid = 0
    100.         SELECT N'引起数据库死锁的是: ' + CAST(@block AS VARCHAR(10))
    101.             +  N'进程号,其执行的SQL语法如下';
    102.     ELSE
    103.         SELECT N'进程号SPID:' + CAST(@spid AS VARCHAR(10)) + N'被进程号SPID:'
    104.             +  CAST(@block AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下';
    105.         
    106.     DBCC INPUTBUFFER(@block )
    107.  
    108.  
    109.     SET @RowIndex = @RowIndex + 1;
    110.  
    111. END;
    112.  
    113.     DROP TABLE #tmp_lock_who;
    114.  
    115.     RETURN 0;
    116. END

    方法5:右键服务器-选择“活动和监视器”,查看进程选项。注意“任务状态”字段。

    方法6:右键服务名称-选择报表-标准报表-活动-所有正在阻塞的事务。


    小结:总结之后,才发现居然有这么多方法,MGD,系统的整理、梳理知识点是非常有必要的,你能更全面、深入的了解。

     
    查看内存状态

    dbcc memorystatus


    具体如何分析,请查看官方文档http://support.microsoft.com/kb/907877/zh-cn

     
    查看脚本执行时间


    方法1: 查看SSMS管理器,查询窗口右下角
    方法2:

    Code Snippet
    1. DECLARE @exectime DATETIME
    2.   SELECT@exectime = GETDATE()
    3. --SQL 语句
    4. PRINT N'SQL执行耗时:' + CONVERT(VARCHAR(10), DATEDIFF(ms, @exectime, GETDATE()))

    方法3:

    SET STATISTICS TIME ON

    --SQL 语句

    查看进程正在执行的SQL语句 

      dbcc inputbuffer ()

    查看那些表缺少索引 

    下面语句功能强大,执行结果受统计信息的影响

    Code Snippet
    1. SELECT sys.objects.name table_name,
    2.        mid.statement full_name,
    3.     (migs.avg_total_user_cost * migs.avg_user_impact) *(migs.user_seeks + migs.user_scans) AS Impact,
    4.     migs.avg_user_impact *(migs.user_seeks + migs.user_scans) Avg_Estimated_Impact,
    5.     'CREATE NONCLUSTERED INDEX IDX_' + sys.objects.name + '_N ON '
    6.         + sys.objects.name COLLATE DATABASE_DEFAULT
    7.         + ' ( ' + IsNull(mid.equality_columns, '')
    8.         + CASE WHEN mid.inequality_columns IS NULL
    9.                 THEN ''
    10.             ELSE
    11.                 CASE WHEN mid.equality_columns IS NULL
    12.                     THEN ''
    13.                 ELSE ','
    14.                 END + mid.inequality_columns
    15.             END + ' ) '
    16.         + CASE WHEN mid.included_columns IS NULL
    17.                 THEN ''
    18.             ELSE 'INCLUDE (' + mid.included_columns + ')' END
    19.         + ';' AS CreateIndexStatement,
    20.     mid.equality_columns,
    21.     mid.inequality_columns,
    22.     mid.included_columns
    23. FROM sys.dm_db_missing_index_group_stats AS migs
    24.     INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle
    25.     INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle
    26.         AND mid.database_id = DB_ID()
    27.     INNER JOIN sys.objects WITH (nolock) ON mid.OBJECT_ID = sys.objects.OBJECT_ID
    28. WHERE (migs.group_handle IN
    29.         (
    30.             SELECT TOP (500) group_handle
    31.             FROM sys.dm_db_missing_index_group_stats WITH (nolock)
    32.             ORDER BY (avg_total_user_cost * avg_user_impact) *(user_seeks + user_scans) DESC))
    33.     AND OBJECTPROPERTY(sys.objects.OBJECT_ID, 'isusertable')=1
    34. --ORDER BY [Impact] DESC, [full_name] DESC
    35. ORDER BY [table_name], [Impact] desc

    查看应该被移除的索引

     

    查看那些多余的、应该被移除的索引

    SQL 1:

    Code Snippet
    1. SELECT OBJECTNAME = OBJECT_NAME(I.OBJECT_ID),
    2.     INDEXNAME = I.NAME,
    3.     I.INDEX_ID
    4. FROM SYS.INDEXES I
    5.     JOIN SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID
    6. WHERE OBJECTPROPERTY(O.OBJECT_ID,'IsUserTable') = 1
    7.     AND I.INDEX_ID NOT IN(
    8.                             SELECT S.INDEX_ID
    9.                             FROM SYS.DM_DB_INDEX_USAGE_STATS S
    10.                             WHERE S.OBJECT_ID = I.OBJECT_ID
    11.                                 AND I.INDEX_ID = S.INDEX_ID
    12.                                 AND DATABASE_ID = DB_ID())
    13. ORDER BY OBJECTNAME, I.INDEX_ID, INDEXNAME ASC

    SQL 2: 分析下面语句,移除那些没有必要的索引

    Code Snippet
    1. SELECT DB_NAME(database_id)         AS  N'DataBaseName'  ,
    2.        OBJECT_NAME(U.object_id)     AS  N'Table_Name'    ,
    3.        I.name                       AS  N'Index_Name'    ,
    4.        user_seeks                   AS  N'用户索引查找次数',
    5.        user_scans                   AS  N'用户索引扫描次数',
    6.        last_user_seek               AS  N'最后查找时间'   ,
    7.        last_user_scan               AS  N'最后扫描时间'   ,
    8.        rows                         AS  N'表中的行数'
    9. FROM sys.dm_db_index_usage_stats AS U
    10.    INNER JOIN sys.indexes I ON U.index_id= I.index_idAND U.object_id= I.object_id
    11.   INNER JOIN sysindexesT ON I.object_id = T.id
    12. WHERE database_id= DB_ID('DbName')
    13. AND OBJECT_NAME(U.object_id)='TableName'
    14. ORDER BY user_seeks, user_scans, object_name(U.object_id);
  • 相关阅读:
    (转载)VS2010/MFC编程入门之三十七(工具栏:工具栏的创建、停靠与使用)
    (转载)VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
    (转载)VS2010/MFC编程入门之三十三(常用控件:标签控件Tab Control 下)
    (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
    ubuntu下格式化u盘
    Android笔记之AppWidget
    Android笔记之ViewPager实现滑动页面
    Android笔记之获取布局中的多个子控件
    Android笔记之Actionbar制作选项卡(可滑动)
    Android笔记之Actionbar使用(二)
  • 原文地址:https://www.cnblogs.com/kerrycode/p/3153321.html
Copyright © 2011-2022 走看看