您的位置:首页 > 数据库

SQL Server 2005性能排错白皮书(Part 1)---From MS Customer Support Service部门

2009-02-24 15:51 225 查看
很少会有偶然的性能下降。设计不良的数据库或工作负载配置不正确的系统会经常导致性能问题。管理员需要能预先阻止或最小化问题的影响,当管理员遇到问题时,应该诊断问题并采取正确操作来修复问题。本文提供了按部就班的指导,通过使用可用的工具例如SQL Server Profiler,System Monitor和在SQL Server 2005中新的Dynamic Management View来为一般的性能问题诊断和排错

目录:简介 目标 方法 资源瓶颈 CPU 瓶颈 内存瓶颈 I/O 瓶颈 tempdb 运行缓慢的查询 总结 附录A: DBCC MEMORYSTATUS描述 附录B: 阻塞脚本

简介

很多客户偶尔会遇到SQL Server 数据库性能下降。原因可能涉及从不良好的数据库设计到不正确的负载配置。作为一个管理员,你应该预先阻止或最小化问题,并当问题发生时,诊断原因并尽可能的做出正确的操作来解决问题。这片白皮书所述的问题通常来源于Microsoft? Corporation 的Customer Support Service(CSS or PSS)部门所遇到的,因为将所有可能的问题都详尽的分析是不合实际的。我们提供了按部就班的指导,通过使用可用的工具例如SQL Server Profiler,System Monitor和在SQL Server 2005中新的Dynamic Management View来为一般的性能问题诊断和排错。

目标

这篇文章的主要目标是提供一套常规的方法通过使用公开的工具在一般的客户场景中诊断和排错SQL Server性能问题。SQL Server 2005在用户支持上有了很大的提高。内核层(SQL-OS)被重新架构过,内部结构和统计数据通过动态管理视图(DMVs)暴露为关系型行集。SQL Server 2000通过像sysprocesses这样的系统表暴露一些信息,但是有时你需要将SQL Server进程内存映射为物理文件并从中抽取内部结构的相关信息。这里有2个主要的问题。第一,客户不能总是提供物理映射文件,因为文件的尺寸原因,并且这个过程很耗时。第二,这将花费更长的时间诊断问题,因为文件必须传回Microsoft Corporation来分析。这带给我们本文的第二个目标,展示DMVs的优点。DMVs通过除去大多数情况下需要的生成和分析物理映射步骤可以加速调试的过程。本文尽可能的提供了和SQL Server 2000中同样问题的比较。DMVs提供为获取关键系统信息的简单而熟悉的界面。这些信息也可以用于监视目的,警告管理员潜在的问题。或者也可以被周期性的收集为以后的分析所用。

方法

这里有很多降低SQL Server速度的原因。我们使用下列3个主要症状来诊断问题。

◆资源瓶颈: CPU,内存,和I/O瓶颈是在本文中主要涉及的。这里我们不考虑网络因素。对每种资源瓶颈,我们会描述如何识别问题并阐述可能的原因。例如,内存瓶颈可以导致过多的分页,最后影响性能。

◆Tempdb 瓶颈:因为每个SQL Server 实例只有一个tempdb,这可以产生性能和磁盘空间的瓶颈。不好的应用程序在过多的DDL和DML操作会使tempdb过载。这导致其他在这台服务器上运行的不相关的应用程序运行缓慢或失败。

◆缓慢运行的用户查询:现有的查询性能下降或新的查询显示比预期时间更长。这可能有很多原因。例如:

◆改变统计信息可以导致现有查询的较差的查询计划。

◆制表扫描,降低查询性能。

◆即使资源利用正常由于阻塞也可以导致应用程序运行缓慢。

过多的阻塞可能是由于不良的应用程序设计或架构设计或者是选择了错误的事务隔离级别的原因。这些症状的原因不需要每个都独立出来。不良的查询计划选择可以使系统资源加重并导致整体性能的下降。所以,如果大表缺失的有用的索引,或查询优化器没有选择它,这样不仅导致查询缓慢,也会导致将不需要数据页读取到内存(buffer pool)中在缓存中存储,这样会加重I/O子系统的压力。同样的,频繁运行查询的重编译可以导致CPU的压力。

资源瓶颈

接下来的部分讨论了CPU,内存和I/O子系统资源及这些瓶颈如何产生。(网络问题不在本文的讨论范围)每个资源瓶颈,我们描述了如何识别问题并找到原因。例如,一个内存瓶颈可以导致过渡分页,将会影响性能。在决定你遇到资源瓶颈前,你需要了解在普通环境下资源是如何使用的。你可以使用在这片白皮书中所列出的方法收集有关资源使用的基线信息(即使你没有遇到性能问题)。

你也许找到问题是一个资源运行到设计容量并且SQL Server当前的配置不能支持这种负载。为了解决这问题,你也许需要添加处理能力,内存或增加I/O的带宽或网络通道。但是,在你进行下一步之前,理解这种资源瓶颈的通常原因是非常重要的。有一些解决方案不需要添加额外资源,例如重新配置。

解决资源瓶颈的工具

下列工具是在解决特殊性能瓶颈时经常使用的工具。

◆系统监视器(PerfMon):这是Windows所带的一个工具。更多信息,请见系统监视器文档。

◆SQL Server Profiler:在SQL Server 2005程序组中的Performance Tools组中可以看到SQL Server Profiler。

◆DBCC 命令:详细信息请见SQL Server联机丛书中和附录A。

◆DMVs: 详细信息请见SQL Server联机丛书。

CPU 瓶颈

当没有额外负载,突然发生的CPU瓶颈通常由于没有查询计划,不良的配置或设计因素和不足的硬件资源所引起。在购买更快或更多处理器前,你需要首先确定CPU的最大处理能力带宽并查看是否他们都在使用中。系统监视器一般是确定CPU资源的最好工具。你应该查看Processor:% Processor Time计数器是否偏高;该计数器值超过80%一般被认为是瓶颈。你也可以使用sys.dm_os_schedulers视图来监视是否正在运行的任务不是0。非0的值预示有任务需要等待时间切片来运行;这个数值高表明一个CPU瓶颈的征兆。你可以用下列查询列出所有的调度器并产看等待运行的任务数量。

select scheduler_id,current_tasks_count,runnable_tasks_countfrom sys.dm_os_schedulerswhere scheduler_id < 255

下列查询给你一个查看当前缓存中最耗费CPU的批或过程高级别视图。查询根据具有相同plan handle(意味着属于同一个批或过程)的语句聚合CPU的调用。如果给出的plan handle对应多个语句,你将不得不继续找到在整个CPU使用中最占用资源的查询。

select top 50 sum(qs.total_worker_time) as total_cpu_time, sum(qs.execution_count) as total_execution_count,count(*) as number_of_statements, qs.plan_handle from sys.dm_exec_query_stats qsgroup by qs.plan_handleorder by sum(qs.total_worker_time) desc

本节剩下的部分将讨论一些其他的在SQL Server 中CPU敏感的操作,也有有效的检查和解决这些问题的方法。

过多的编译和重编译

当批或远端过程调用(RPC)被提交到SQL Server,在开始执行前,服务器检查查询计划的有效性和正确性。如果这些检查中的一个失败时,批将被再次编译声称不同的查询计划。

这种编译就是所说的重编译。当服务器确认当底层数据改变时有更优化的查询计划时,重编译确认正确性再完成编译。编译是CPU敏感的,因此过多的重编译将导致在系统中的CPU性能问题。

在SQL Server 2000中,当SQL Server重编译一个存储过程,整个存储过程都被重编译,不仅是触发重编译的语句。SQL Server 2005引入了语句级的存储过程的重编译。当SQL Server 2005重编译存储过程,只有导致重编译的语句被编译-而不是整个存储过程。这减少了CPU的负载并减少了对例如COMPILE锁的资源争用。重编译可以有多种原因出发,例如:

◆架构变化

◆统计变化

◆延期编译

◆Set属性改变

◆临时表改变

◆存储过程创建时使用了RECOMPLIE查询提示或使用了OPTION (RECOMPILE)。

检测

你可以使用系统监视器(PerfMon)或SQL Trace(SQL Server Profiler)来检测过多的编译和重编译。

系统监视器(Perfmon)

SQL Statistics对象提供了监视重编译的计数器和发送到SQL Server实例的请求类型。你必须监视查询编译和重编译的数量以及相关联的接受的批的数量来找出是否这个编译是最耗费CPU资源。理想环境下,SQL Recompilations/sec和Batch Request/sec的比值应该很低,除非用户提交了大量的单独查询。

下列显示了关键的数据计数器。

◆SQL Server: SQL Statistics: Batch Requests/sec

◆SQL Server: SQL Statistics: SQL Compilations/sec

◆SQL Server: SQL Statistics: SQL Recompilations/sec

更多信息请看SQL Server联机丛书中的 “SQL Statistics Object”

SQL 跟踪

如果PerfMon计数器显出了很高的重编译数量,编译将在SQL Server中占用很多的CPU资源。我们将需要查看Profiler 跟踪并从中找到找到被重编译的存储过程。SQL Server Profiler跟踪给出我们重编译原因的信息。你可以使用下列事件。

SP:Recompile和SQL:StmtRecompile事件类指出了哪个存储过程和语句被重编译。当你编译一个存储过程,一个事件为这个存储过程生成,其中每条语句将被编译。然而,当存储过程重编译时,只有导致重编译的语句被重编译(在SQL Server 2000中将是整个存储过程)。下面列出了SP:Recompile事件类更多重要的数据列。特别EventSubClass数据列决定重编译的原因。SP:Recompile当存储过程或触发器被重编译被触发一次,但不会被独立查询引发。在SQL Server 2005中,监视SQL:StmtRecompiles也非常有用,该事件类在所有类型的重编译中都会被触发,包括批,独立查询,存储过程和触发器。如下是我们关系的事件中关键的数据列:

◆EventClass

◆EventSubClass

◆ObjectID (represents stored procedure that contains this statement)

◆SPID

◆StartTime

◆SqlHandle

◆TextData

更多信息,请见SQL Server 联机丛书中“SQL:StmtRecompile Event Class”。如果你有保存的跟踪文件,你可以使用下列查询查看所有捕捉的重编译事件。

select spid,StartTime,Textdata,EventSubclass,ObjectID,DatabaseID,SQLHandle from fn_trace_gettable ( 'e:\recompiletrace.trc' , 1)where EventClass in(37,75,166)

事件类37是 Sp:Recompile, 75 是 CursorRecompile, 166是SQL:StmtRecompile

你可以通过SqlHandle和ObjectID列或其他列将这个查询的结果分组,也可以查看是否最多的重编译类型是存储过程或其他原因(例如SET选项改变等)。

Showplan XML For Query Compile. Showplan XML For Query Compile事件发生于Microsoft SQL Server编译或重编译一段SQL语句时。该事件有关于语句编译或重编译的信息。信息包括查询计划和过程的对象ID。

捕获这些事件是有性能开销的,因为它捕获了每次编译或重编译。如果你在系统监视其中看到很高的SQL Compilations/sec计数器值,你应该监视这个事件。通过这些信息,你可以看到那条语句被频繁的重编译。你可以使用这些信息改变这些语句的参数。这将影响重编译的数量。

DMVs.

当你使用sys.dm_exec_query_optimizer_info DMV,你可以得到SQL Server花费在优化的时间。如果获取了这个DMV的2个快照,你可以得到在给定的时间段内花费在查询优化的时间。

select * from sys.dm_exec_query_optimizer_infocounter occurrence value ---------------- -------------------- --------------------- optimizations 81 1.0elapsed

time 81 6.4547820702944486E-2

特别是查看elapsed time,该时间由于优化而产生。因为优化过程的时间基本上就是用户优化操作的CPU时间(因为优化处理是CPU时间的主要部分),你可以得到一个好的度量,找到那段编译时间占用了大量的CPU时间。其他包含有用信息的DMV有:

sys.dm_exec_query_stats.

你希望查看的数据列有:

◆Sql_handle

◆Total worker time

◆Plan generation number

◆Statement Start Offset

更多信息请查看SQL Server 联机丛书相关主题

sys.dm_exec_query_stats.

特别是plan_generation_num预示了查询编译时的次数。下面是示例给你展示了被重编译次数最多的25个存储过程。

select * from sys.dm_exec_query_optimizer_infoselect top 25sql_text.text,sql_handle,plan_generation_num,execution_count,dbid,objectid from sys.dm_exec_query_stats across apply sys.dm_exec_sql_text(sql_handle) as sql_textwhere plan_generation_num >1order by plan_generation_num desc

更多信息请见Batch Compilation, Recompilation, and Plan Caching Issues in SQL Server 2005

解决

如果你监测到过多的编译/重编译,考虑下列选项。

◆如果重编译因为SET选项改变而发生,使用SQL Server Profiler确定哪个SET选项被改编。避免在存储过程中改变SET选项。如果改变最好在连接级别设置。确认在该连接的生存周期内不要改变SET选项。

在临时表上重编译的阀值比在普通表上的低。在临时表上的重编译时由于统计改变而引起,你可以降临时表改为使用表变量。表变量的改变不会引起重编译。这种方法的确定是查询优化器不识别表变量,因为统计不会被创建或维护表变量。这将导致没有查询计划。你可以测试不同的选项,并选择最好的方法。另外一个选项时使用KEEP PLAN查询提示。

设置临时表的这个阀值与使用永久表相同。

EventSubclass 列预示了在临时表上的”Statistics Changed”的操作。

◆为避免由于改变统计而产生的重编译(例如,因为数据统计导致计划不理想),特别是KEEPFIXED PLAN查询提示。根据设置的影响,重编译可以仅因为相关正确的原因(例如,当底层表结构改变导致计划不再适用),而不根据统计的变化。如果语句引用的表的架构改变时或者表是被标记为sp_recompile的存储过程,重编译将发生。

◆关闭自动更新索引统计和表或视图的统计,防止由于对象的统计改变而产生的重编译。注意,通过使用这种方法关闭”auto-stats”特性不是一个好的想法。这是因为查询优化器不再为在这些对象上的数据改变而敏感,将导致不良的查询计划。使用这种方法仅在尝试了所有其他选择之后,做为最后的手段。

◆批应该尽量使用对象全名(例如,dbo.Table1)避免重编译并避免不明确的对象。

◆为避免由于延期编译导致的重编译,不要混杂DML和DDL或从条件结构创建DDL,例如IF语句。

◆运行Database Engine Tuning Advisor(DTA)查看改变索引是否可以改善编译时间和查询的执行时间。

◆检查是否存储过程通过WITH RECOMPILE选项创建或使用了RECOMPILE查询提示。如果过程通过WITH RECOMPILE选项创建,在SQL Server 2005中,如果在过程中特殊的语句需要被重编译,我们可以利用语句级的RECOMPILE提示。这将避免在每次执行的时候对整个过程重编译,而同时允许个别语句被编译。更多有关RECOMPILE提示的信息,请查看SQL Server联机丛书。

效率低的查询计划

当为一个查询生成查询计划时,SQL Server查询优化器尝试选择一个计划为查询提供最快的响应时间。注意最快的查询时间并不意味最小的I/O开销,也不意味使用最少的CPU资源-它会在各种资源中平衡。

某些操作类型比其他操作对CPU更敏感。Hash操作和Sort操作扫描他们各自的输入数据。使用扫描向前读取(prefetch)时,在需要操作页面前,页面几乎都在缓存中。因此可以减少或消除物理I/O操作。这使这些操作的类型将不被物理I/O所限制。与之相比,嵌套循环连接有很多索引查找,如果索引查找使用很多不同的表以至于页面不适合缓存的大小,将导致生成I/O负载。

最有意义的输入优化用于评估为每中操作生成不同查询计划开销的评估,你可以在Showplan(EstimateRows和EstimateExecution属性)中看到结果。没有精确的评估,用于优化的主输入是有缺陷的。为获取SQL Server优化器如何使用统计的详细信息,请查看 Statistics Used by the Query Optimizer in Microsoft SQL Server 2005 。该白皮书讨论了优化器如何使用统计,维护和更新统计的最佳实践,以及一些常见的查询设计问题。

检测

低效率的查询计划通常可以被检测出来。低效率的查询计划可以导致增加CPU的消耗。查询sys.dm_exec_query_stats是确定哪个查询累计使用CPU时间最多的有效方法。

select highest_cpu_queries.plan_handle, highest_cpu_queries.total_worker_time,q.dbid,q.objectid,q.number,q.encrypted,q.[text]from (select top 50 qs.plan_handle, qs.total_worker_timefrom sys.dm_exec_query_stats qsorder by qs.total_worker_time desc) as highest_cpu_queriescross apply sys.dm_exec_sql_text(plan_handle) as qorder by highest_cpu_queries.total_worker_time desc

还可以选择,也可以查询sys.dm_exec_cached_plans并通过使用过滤器查找可疑的类似于‘%Hash Match%’, ‘%Sort%’这样CPU敏感的各种操作。

解决

如果你监测到效率低的查询计划,考虑下列选项。

◆使用Database Engine Tuning Advisor调节查询,查看是否生成对修改索引的建议

◆检查有问题的评估。

编写的查询中使用的更有限制性的WHERE从句是否合适?无限制条件的查询是资源敏感的。

在查询中涉及的表上运行UPDATE STATISTICS,检查是否还有这种问题。

是否查询使用的构造导致优化器不能精确的评估?

考虑是否可以将查询修改为其他的方法,避免这种问题。

◆如果不能修改架构或查询,SQL Server 2005有一个新的查询计划特性,允许你将指定查询提示添加到满足某种文本的查询中。这可以用在独立查询中,也可以用在存储过程内。例如OPTION(OPTIMIZE FOR)这样的提示允许你影响评估而忘记所有列出的潜在计划。其他的提示,类似OPTION(FORCE ORDER)或 OPITON(USE PLAN)允许你改变控制查询计划的程度。

内部查询的并行

当为一个查询生成执行计划时,SQL Server优化器尝试为该查询选择最快的相应计划。如果查询的开销超过了在cost threshold for parallelism选项中指定的值,并行不会被禁用,优化器尝试生成一个可以用于并行的计划。并行查询计划使用多线程处理查询,每个线程分布在可用的CPU上并同时利用每个CPU的时间资源。最大的并行度可以通过服务器上的max degree of parallelism选项或每个查询使用OPTION(MAXDOP)提示限制。

用于执行实际并行度(DOP)的结果——度量有多少线程将在给定的操作上并行——是知道执行时才能确定。在执行查询前,SQL Server 2005决定有多少个调度器未充分利用并为查询选择DOP来充分利用剩余的调度器。一旦一个DOP被选择了,直到完成,查询将使用这个选择的并行度来运行。并行查询的使用时CPU有一些偏高,但是它在elapsed time上的时间很短。如果没有其他瓶颈,类似于物理I/O等待,并行计划将会使用所有处理器的100%资源。查询开始执行后,一个关键的因素(系统有多空闲)可以导致运行并行计划的改变。例如,如果查询运行在空闲时间,服务器可以选择使用并行计划并使用DOP为4,在4个不同的处理器上产生线程。一旦这种线程开始执行,现存的连接可以提交其他需要大量CPU的查询。在这种情况,所有不同的线程将共享可用的CPU的时间切片,导致更高的查询持续时间。

通过并行计划运行不是一定是不好的,并行可以为查询提供最快的响应时间。然而,给定查询的响应时间必须与整体的吞吐量和系统其他查询的响应进行衡量。并行查询一般最适合批处理和决策支持系统,而不适合一个事务处理环境。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: