Sql Server2005性能诊断


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
引用:http://technet.microsoft.com/zh-cn/library/cc966540(en-us).aspx
Sql Server速度变慢问题主要由三个方面引起,可从这三个方面入手分析问题
  1,资源瓶颈:CPU、I/O、内存等。
  2,临时表瓶颈:tempdb各个数据库共用,资源紧张时会引起性能降低。
  3,用户比较耗时的sql查询。

一,CPU瓶颈分析。瓶颈症状:打开perfmon, 监视 processor:% Processor Time若长期>80%,或者任务管理器,说明可能是CPU原因。
1,分析是否是查询语句引起
 这里涉及一个动态视图:sys.dm_exec_query_stats,返回每条查询语句运行的时间
关键栏位有:
 1)sql_handle:表示包含查询的批查询或存储过程的标记,若sql_handle相同,代表查询在同个批处理或同一个存储过程内。可将此值传入    sys.dm_exec_sql_text中获取查询语句。同个存储过程或批处理语句的sql_handle相同,如何分辨是哪个查询语句得到了执行,
可用statement_start_offset、statement_end_offset来查出此查询语句的真容。
2)statement_start_offset:查询在其批查询或持久化对象文本中的开始位置
3)statement_end_offset:查询在其批查询或持久化对象文本中的结束位置
4)execution_count: 计划自上次编译以来所执行的次数。
5)total_worker_time:此计划自编译以来执行所用的 CPU 时间总量(以微秒为单位报告,但仅精确到毫秒)。
6)last_execution_time:上次开始执行计划的时间。
故分析耗CPU语句方法可得出:

--若返回的dbname,objectname为空,代表是动态sql语句,不是存储过程
SELECT 
    dbname,ObjectName,Sql,
    SUM([总消耗CPU 时间(ms)]) [总消耗CPU 时间(ms)],
    SUM([运行次数])[运行次数],[查询语句],[所在存储过程],
    SUM([平均消耗CPU 时间(ms)])[平均消耗CPU 时间(ms)]    
    FROM (
    SELECT TOP (50)
        qs.total_worker_time/qs.execution_count/1000. as [平均消耗CPU 时间(ms)],
        total_worker_time/1000 AS [总消耗CPU 时间(ms)],execution_count [运行次数],
       
        dbo.SQLSig(SUBSTRING(qt.text,qs.statement_start_offset/2+1, --利用sqlsig函数进行参数化,以屏蔽传来的参数,使之标准化
            (case when qs.statement_end_offset = -1
            then DATALENGTH(qt.text)
            else qs.statement_end_offset end -qs.statement_start_offset)/2 + 1),4000)
        as [查询语句], qt.text [所在存储过程],
        qt.dbid, dbname=db_name(qt.dbid),
        qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName
    FROM sys.dm_exec_query_stats qs
    cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
    ORDER BY [平均消耗CPU 时间(ms)] DESC
    )M
    GROUP BY [查询语句],[所在存储过程],dbid, dbname,objectid,ObjectName
    ORDER BY [平均消耗CPU 时间(ms)] DESC

注:测试sys.dm_exec_query_stats 时可先清除缓存DBCC FREEPROCCACHE 再执行查询语句分析。

2,分析是否是重新编译引起,重新编译比较费时。
1)perfmon:

    SQL Server: SQL Statistics: Batch Requests/sec :每秒钟接收的请求数

    SQL Server: SQL Statistics: SQL Compilations/sec:每秒钟的编译数

    SQL Server: SQL Statistics: SQL Recompilations/sec:每秒钟的重新编译数

2)profile:SP:Recompile / SQL:StmtRecompile.
3)sys.dm_exec_query_stats 有一个栏位plan_generation_num,计划编译次数,可用此来分析最常编译的计划。
select top 25
    plan_generation_num,
    SUBSTRING(qt.text,qs.statement_start_offset/2+1,
        (case when qs.statement_end_offset = -1
        then DATALENGTH(qt.text)
        else qs.statement_end_offset end -qs.statement_start_offset)/2 + 1)
        as stmt_executing,
    qt.text,
    execution_count,
    sql_handle,
    dbid,
    db_name(dbid) DBName,
    objectid,
    object_name(objectid,dbid) ObjectName
from sys.dm_exec_query_stats as qs
    Cross apply sys.dm_exec_sql_text(sql_handle) qt
where plan_generation_num >1
--AND qs.last_execution_time >='2011-08-28 10:00' 限定时间
order by plan_generation_num desc



二,内存瓶颈分析。瓶颈症状:打开perfmon, 监视 Paging File: %Usage长期>80%。Paging File:Usage: 分页空间使用百分率

三,I/O瓶颈分析:症状:计数器PhysicalDisk:%Disk Time >80% , Avg.Disk Queue Length:>2
1,%Disk Time :所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。
Avg. Disk Queue Length 指读取和写入请求(为所选磁盘在实例间隔中列队的)的平均数。
不过,若出现上述情况,也可以是内存不足引起。

2,sys.dm_exec_query_stats 有栏位total_logical_writes:此计划自编译后在执行期间所执行的逻辑写入总次数。total_logical_reads:此计划自编译后在执行期间所执行的逻辑写入总次数。
故查询最耗I/O的语句为:

select top 50
(total_logical_reads/execution_count) as [平均逻辑读取次数],
(total_logical_writes/execution_count) as [平均逻辑写入次数],
(total_physical_reads/execution_count) as [平均对象读取次数],
 Execution_count 运行次数,
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_query_stats  as r
    cross apply sys.dm_exec_sql_text(r.sql_handle) as qt
--WHERE r.last_execution_time >='2011-08-28 10:00' 限定时间
order by
 (total_logical_reads + total_logical_writes) Desc

四,tempdb瓶颈。空间资源耗尽引起。
查询:
Select
    SUM (user_object_reserved_page_count)*8 as user_objects_kb,
    SUM (internal_object_reserved_page_count)*8 as internal_objects_kb,
    SUM (version_store_reserved_page_count)*8  as version_store_kb,
    SUM (unallocated_extent_page_count)*8 as freespace_kb
From sys.dm_db_file_space_usage
Where database_id = 2
其中:freespace_kb  要足够大才可。