zoukankan      html  css  js  c++  java
  • 日常工作中常用到的sql脚本

     一 从数据字典中查看大表

    SELECT   a.name AS 表名, MAX(b.rows) AS 记录条数
    FROM     sys.sysobjects AS a INNER JOIN
             sys.sysindexes AS b ON a.id = b.id
    WHERE   (a.xtype = 'u')
    GROUP BY a.name
    --当前数据库,数据文件占用与剩余空间
    SELECT DB_NAME() AS DbName,
           name AS FileName,
           size/128.0 AS CurrentSizeMB,
           size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT)/128.0 AS FreeSpaceMB
    FROM sys.database_files;
    --查看当前数据库中超过50MB的大表
    Declare @SizeMB INT = 50;
    SELECT DB_NAME() AS DbName,
        s.Name AS SchemaName,
        t.NAME AS TableName,
        p.rows AS RowCounts,
        --SUM(a.total_pages) * 8 AS TotalSpaceKB, 
        CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
        --SUM(a.used_pages) * 8 AS UsedSpaceKB, 
        CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, 
        --(SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
        CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
    FROM sys.tables t
    INNER JOIN  sys.indexes i ON t.OBJECT_ID = i.object_id
    INNER JOIN  sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
    INNER JOIN  sys.allocation_units a ON p.partition_id = a.container_id
    LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id
    WHERE t.NAME NOT LIKE 'dt%' 
      AND t.is_ms_shipped = 0
      AND i.OBJECT_ID > 255 
    GROUP BY t.Name, s.Name, p.Rows
    HAVING SUM(a.total_pages) * 8 / 1024.00>@SizeMB
    ORDER BY p.rows desc;

    二 查看IO消耗最大的TOP 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
     (total_logical_reads + total_physical_reads) /Execution_count Desc

     三  计算signal wait占整wait时间的百分比

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

    select convert(numeric(5,4),sum(signal_wait_time_ms)*1.0/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*1.0/@Sumwaits)

      查看TOP 10 等待类型  

    select top 10 wait_type,convert(numeric(5,4),wait_time_ms*1.0/b.total_wait_time_ms)*100 as 'Ratio%'
      from sys.dm_os_wait_stats a 
      cross join (select sum(wait_time_ms) as total_wait_time_ms from Sys.dm_os_wait_stats) b
      where wait_type NOT IN (
            N'BROKER_EVENTHANDLER',             N'BROKER_RECEIVE_WAITFOR',
            N'BROKER_TASK_STOP',                N'BROKER_TO_FLUSH',
            N'BROKER_TRANSMITTER',              N'CHECKPOINT_QUEUE',
            N'CHKPT',                           N'CLR_AUTO_EVENT',
            N'CLR_MANUAL_EVENT',                N'CLR_SEMAPHORE',
            N'DBMIRROR_DBM_EVENT',              N'DBMIRROR_EVENTS_QUEUE',
            N'DBMIRROR_WORKER_QUEUE',           N'DBMIRRORING_CMD',
            N'DIRTY_PAGE_POLL',                 N'DISPATCHER_QUEUE_SEMAPHORE',
            N'EXECSYNC',                        N'FSAGENT',
            N'FT_IFTS_SCHEDULER_IDLE_WAIT',     N'FT_IFTSHC_MUTEX',
            N'HADR_CLUSAPI_CALL',               N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
            N'HADR_LOGCAPTURE_WAIT',            N'HADR_NOTIFICATION_DEQUEUE',
            N'HADR_TIMER_TASK',                 N'HADR_WORK_QUEUE',
            N'KSOURCE_WAKEUP',                  N'LAZYWRITER_SLEEP',
            N'LOGMGR_QUEUE',                    N'ONDEMAND_TASK_QUEUE',
            N'PWAIT_ALL_COMPONENTS_INITIALIZED',
            N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP',
            N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP',
            N'REQUEST_FOR_DEADLOCK_SEARCH',     N'RESOURCE_QUEUE',
            N'SERVER_IDLE_CHECK',               N'SLEEP_BPOOL_FLUSH',
            N'SLEEP_DBSTARTUP',                 N'SLEEP_DCOMSTARTUP',
            N'SLEEP_MASTERDBREADY',             N'SLEEP_MASTERMDREADY',
            N'SLEEP_MASTERUPGRADED',            N'SLEEP_MSDBSTARTUP',
            N'SLEEP_SYSTEMTASK',                N'SLEEP_TASK',
            N'SLEEP_TEMPDBSTARTUP',             N'SNI_HTTP_ACCEPT',
            N'SP_SERVER_DIAGNOSTICS_SLEEP',     N'SQLTRACE_BUFFER_FLUSH',
            N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
            N'SQLTRACE_WAIT_ENTRIES',           N'WAIT_FOR_RESULTS',
            N'WAITFOR',                         N'WAITFOR_TASKSHUTDOWN',
            N'WAIT_XTP_HOST_WAIT',              N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG',
            N'WAIT_XTP_CKPT_CLOSE',             N'XE_DISPATCHER_JOIN',
            N'XE_DISPATCHER_WAIT',              N'XE_TIMER_EVENT')
    order by wait_time_ms*1.0/b.total_wait_time_ms desc

    五 查询当前数据库上所有用户表格在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

    六 检查索引的使用情况

    select db_name(database_id) as N'数据库名称',
           object_name(a.object_id) as N'表名',
           b.name N'索引名称',
           user_seeks N'用户索引查找次数',
           user_scans N'用户索引扫描次数',
           last_user_seek N'最后查找时间',
           last_user_scan N'最后扫描时间',
           rows as N'表中的行数'
    from sys.dm_db_index_usage_stats a join 
         sys.indexes b
         on a.index_id = b.index_id
         and a.object_id = b.object_id
         join sysindexes c
         on c.id = b.object_id
    where database_id=db_id('WMSDB_FG')   --指定数据库
         and object_name(a.object_id) not like 'sys%'
         --and object_name(a.object_id) like '表名'  --指定索引表
        -- and b.name like '索引名' --指定索引名称 可以先使用 sp_help '你的表名' 查看表的结构和所有的索引信息
    order by user_seeks,user_scans,object_name(a.object_id)

    七 检查缓冲区的命中率

    SELECT (a.cntr_value * 1.0 / b.cntr_value) * 100.0 [BufferCacheHitRatio]
    FROM (SELECT * FROM sys.dm_os_performance_counters
    WHERE counter_name = 'Buffer cache hit ratio'
    AND object_name = CASE WHEN @@SERVICENAME = 'MSSQLSERVER'
    THEN 'SQLServer:Buffer Manager'
    ELSE 'MSSQL$' + rtrim(@@SERVICENAME) +
    ':Buffer Manager' END ) a
    CROSS JOIN
    (SELECT * from sys.dm_os_performance_counters
    WHERE counter_name = 'Buffer cache hit ratio base'
    and object_name = CASE WHEN @@SERVICENAME = 'MSSQLSERVER'
    THEN 'SQLServer:Buffer Manager'
    ELSE 'MSSQL$' + rtrim(@@SERVICENAME) +
    ':Buffer Manager' END ) b;

     八 查看数据库从上次启动以来所发生的死锁的次数

    SELECT instance_name,cntr_value AS NumOfDeadLocks
    FROM sys.dm_os_performance_counters
    WHERE object_name = 'SQLServer:Locks'
    AND counter_name = 'Number of Deadlocks/sec'
    AND instance_name = '_Total'

    九 获取一段时间内累计的File reads

    --1.先执行下面的语句
    SELECT DB_NAME(mf.database_id) AS databaseName ,
    mf.physical_name ,
    divfs.num_of_reads ,
    --other columns removed in this section. See Listing 6.14 for complete code
    GETDATE() AS baselineDate
    INTO #baseline
    FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS divfs
    JOIN sys.master_files AS mf ON mf.database_id = divfs.database_id
    AND mf.file_id = divfs.file_id; 
    
    --2.过一段时间后执行下面的SQL 
    WITH currentLine
    AS ( SELECT DB_NAME(mf.database_id) AS databaseName ,
    mf.physical_name ,
    num_of_reads ,
    --other columms removed
    GETDATE() AS currentlineDate
    FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS divfs
    JOIN sys.master_files AS mf
    ON mf.database_id = divfs.database_id
    AND mf.file_id = divfs.file_id
    )
    SELECT currentLine.databaseName ,
    currentLine.physical_name ,
    --gets the time difference in milliseconds since the baseline was taken
    DATEDIFF(millisecond,baseLineDate,currentLineDate) AS elapsed_ms,
    --gets the change in time since the baseline was taken
    currentLine.num_of_reads - #baseline.num_of_reads AS num_of_reads
    --other columns removed
    FROM currentLine
    INNER JOIN #baseline ON #baseLine.databaseName = currentLine.databaseName
    AND #baseLine.physical_name = currentLine.physical_name

     

    十. 如何监控TempDB的IO瓶颈

      1. 三个windows 性能计数器   

    -- 每次数据传输的平均时间
    a) AVG.Disk sec/Transfer--磁盘读数据所需的平均时间
    b) AVG.Disk sec/Read--磁盘写数据所需的平均时间
    c)AVG.Disk sec/Write

    2.DMV视图

      下面使用sys.dm_io_virtual_file_stats来确认IO瓶颈,它返回数据文件和日志文件的 I/O 统计信息,包括对文件发出的读取/写入次数以及总字节数, file_id字段中1 是数据文件,2是日志文件,脚本如下: 

     SELECT DB_NAME(database_id) AS 'DBName',
            file_id,
            io_stall_read_ms/num_of_reads AS 'Avg Read ms/Transfer',
            io_stall_write_ms/num_of_writes AS 'Avg Write ms/Transfer'
      FROM sys.dm_io_virtual_file_stats(NULL,null) a
     WHERE  database_id = 2  

      下面是数据文件及日志文件性能指标建议列表,仅供参考

    数据文件 日志文件
    目标:<10ms 目标:<5ms
    可接受:10 ~ 20 ms 可接受:5~15ms
    不可接受:>20ms 不可接受:>15ms

     3.查看tempdb空间使用情况

    user_object_reserved_page_count 用户对象包括: 临时表,表变量,表值函数中返回的表,定义的表和索引
    internal_object_reserved_page_count 内部对象包括:排序段,哈希联接,游标
    version_store_reserved_page_count 行版本包括: 触发器,运行联机索引,快照隔离级别或使用行版本控制
    unallocated_extent_page_count:未分配空间(可用空间) 

    select  'Tempdb' as DB,
            GETDATE() as  [Time],
            SUM(user_object_reserved_page_count)*8.0/1024     as  '用户对象占用总空间_M',
            SUM(internal_object_reserved_page_count)*8.0/1024 as '内部对象占用总空间_M',
            SUM(version_store_reserved_page_count) * 8.0/1024 as '行版本占用总空间_M',
            SUM(unallocated_extent_page_count) *8.0/1024      as '未分配总空间_M'
      from sys.dm_db_file_space_usage
     where database_id=2 

     十一 使用性能计数器检测SQL SERVER服务器是否存在IO瓶颈

    可以使用性能计数器来检查I/O子系统的负荷。下面的计数器可用于检查磁盘性能:

    PhysicalDisk Object:Avg.DiskQueue Length:计算从物理磁盘中的平均读和写的请求队列。过高的值代表磁盘操作处于等待状态。当这个值在SQLServer峰值时长期超过2,证明需要注意了。如果有多个硬盘,就需要把这些数值除以2。比如,有4个硬盘,且队列为10,那么平均值就是10/4=2.5,虽然也证明需要关注,但不能使用10这个值。

    Avg.Disk Sec/ReadAvg.Disk Sec/Write:显示从磁盘读或者写入磁盘的平均时间。10ms内是很好的表现,20以下还算能接受。高于此值证明存在问题。

    Physical Disk:%Disk Time:在磁盘忙于读或者写请求的时候持续时间的比率。根据拇指定律,此值应该小于50%

    Disk Reads/SecDisk Writes/Sec计数器显示出在磁盘中读写操作的速率。这两个值应该小于磁盘能力的85%。当超过此值,磁盘的访问时间将以指数方式增长。

    可以通过以下方式来计算逐渐增长的负载的能力。一种方法是使用SQLIO。你应该找到吞吐量比较稳定,但缓慢增长。

    可以使用以下公式来计算RAID配置:

    Raid 0: I/O per disk = (reads + writes) / number ofdisks
    Raid 1: I/O per disk = [reads + (writes*2)] / 2
    Raid 5: I/O per disk = [reads + (writes*4)] / number of disks
    Raid 10: I/O per disk = [reads + (writes*2)] / number of disks

    比如:对于RAID 1,如果得到下面的计数器:

    Disk Reads/sec = 90
    Disk Writes/sec =75
    • 1
    • 2

    根据公式:[reads + (writes*2)] / 2 or [90 + (75*2)] / 2 = 120I/OS每个磁盘。

     

     

  • 相关阅读:
    存储器
    存储器
    存储器
    计算机组成原理目录
    锁原理
    锁原理
    并发编程
    Java 算法
    Java 数据结构
    Java数据结构
  • 原文地址:https://www.cnblogs.com/yuchsheng/p/14067275.html
Copyright © 2011-2022 走看看