怎样查出SQLServer的性能瓶颈

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址

如果你曾经做了很长时间的DBA,那么你会了解到SQLServe的性能调优不是一个精密的科学。即使是,对于为最佳的性能找到最佳的配置也是很困难的。这是因为对于调优来说很少东西是绝对的。例如,一个性能调优可能对某一方面有用,可是却会影响其他的性能。

我曾经做过DBA,在最后7年的日子里,我总结了一套SQLServer调优的清单。当第一次进行SQLServer性能调优的时候,可以用它来作为一个向导。我经常被邀请去检查SQLServer并提供一些性能方面的建议。直到现在,我还没有真正写下一个贯穿整个性能调优过程的方案。但是当我做了越来越多的性能调优的咨询工作后,我现在决定花点时间整理出来。你将会发现它是很有用的,就象我发现对我的用处一样.

SQLServer性能监控

这套性能优化的清单将至少准科学的帮助你找出你的SQLServer任何明显的性能问题。说是这样说,SQLServer的性能调优仍然是很困难的。我试图用这套清单去找出“容易”的sqlserver性能问题,困难的留待稍后。我这样做是因为很容易将容易和困难的的性能调优问题搞混。通过列出一个“容易”的性能调优范围,就很容易的将这些问题解决,一旦解决了这些容易的问题,那么你就能集中去解决更困难的问题。

使用这个SQLServer性能调优清单的一个好处是,它将不仅仅告诉你目前最容易解决的性能问题是什么,而且还帮助你正确的去解决。在某种程度上,你可以选择不同的顺序进行。换句话说,你可以故意做出特殊的决定而不是按照清单通常的顺序进行。某种意义上说你是对的,不是所有的性能调优建议都适合所有的情形。另外,你的决定是基于你的资源限制,例如没有足够的钱去买满足负荷的硬件。如果真是那样的话,你就别无选择了。还有,你的决定可能基于一些政治原因,那是你不得不作出的改变。不管怎样,你需要知道你能做什么,使用这个性能调优清单找出你能改变的范围并做出相应的改变提升你的SQLServer的性能。

一般来说,你将在你的每一个SQL服务器上执行这个清单。如果遇到清单中的一些问题,这会花掉你一些时间。我建议你从目前性能问题最多的的服务器开始,然后当你有时间的时候按照自己的思路去解决其他服务器。

一旦你完成了,可仍然有很多事情要去做。记住,这些只是一些容易的。一旦你完成了这些容易的,接下来你需要花时间去解决更困难问题。这个是另一篇文章要解决的问题了。

怎样进行你的SQLServer性能调优呢?

为了使其变得容易,我把它们分成了以下几个部分:
? 使用性能监视器找出硬件瓶颈
? SQLServer硬件性能监控列表
? 操作系统性能监控列表
? SQLServer2000配置性能监控列表
? 数据库配置设置性能监控列表
? 索引性能监控列表
? 应用程序和T-SQL性能监控列表
? SQLServer数据库作业性能监控列表
? 使用Profiler找出低效的查询
? 怎样最好的实现SQLServer性能监控
管理你的SQLServe性能的最好方法是首先回顾上面每一部分的内容,把它们打印出来。然后完成每一部分的内容,写下你收集到的结果。你也可以按照你喜欢的顺序进行。上面的步骤仅仅列出了我执行的顺序,因为那样通常能达到一个比较好的效果。

性能监控列表
计数器名称 均值 最小值 最大值
Memory: Pages/sec
Memory: Available Bytes
Physical Disk: % Disk time
Physical Disk: Avg. Disk Queue Length
Processor: % Processor Time
System: Processor Queue Length
SQL Server Buffer: Buffer Cache Hit Ratio
SQL Server General: User Connections

在上表输入你的结果.

使用性能监视器找出SQLServer硬件瓶颈

开始SQLServer性能调优的最佳地方就是从性能监视器(系统监视器)开始。通过一个24小时的周期对一些关键的计数器进行监控,你将对你SQLServer服务器的硬件瓶颈了如指掌。

一般来说,使用性能监视器去创建一个一些关键的计数器的24小时周期的监控日志。当你决定创建这个日志的时候,你需要选择一个典型的24小时的周期,例如,选择一个典型的比较忙的日期,而不是周日或节假日。

一旦你将这些捕获的数据形成日志后,在性能监视器的图形界面下会显示计数器的推荐值。你在上表中记下均值、最小值、峰值。做完这些后,用你的结果跟下面的分析比较。通过你的结果和下面的建议值进行比较,你将能快速的找到你的SQLServe正在经历的潜在的硬件瓶颈。

关键性能计数器说明

下面是不同关键性能计数器的一个讨论,它们的建议值和为了帮助解决硬件瓶颈问题的一些选项。注意我已经限制了性能监视器需要监视的一些关键计数器。我这么做是因为在本文我们的目的是为了容易的找到显而易见的性能问题,许多其他的性能监视器计数器你能在本网站其他地方找到。


Memory: Pages/sec

这个计数器记录的是每秒钟内存和磁盘之间交换的页面数。交换更多的页面、超过你服务器承受的更多的I/O,将轮流降低你SQLserver的性能。你的目的就是尽量将页面减少到最小,而不是消除它。

如果你的服务器上SQLServer是最主要的应用程序,那么这个值的理想范围是0~20之间。可能很多时候你看到的值都会超过20。这个值一般要保持在每秒的平均页数在20以下。

如果这个值平均总是超过20,其中最大的一个可能是内存瓶颈问题,需要增加内存。通常来说,更多的内存意味着需要执行的页面更少。
在大多数情况下,服务器决定SQLServer使用的适当内存的大小,页面将平均小于20。给SQLServer适当的内存意味着服务器的缓存命中率(Buffer Hit Cache Ratio 这个稍后会讲到)达到99%或者更高。如果在一个24小时的周期里你的sqlserver的缓存命中率达到99%或者更高,但是在这个期间你的页面数总是超过20,这意味着你或许运行了其他的程序。如果是这样的情况,建议你移除这些程序,使SQLServer是你的服务器的最主要的程序。

如果你的sqlserver服务器没有运行其他程序,并且在一个24小时的周期里页面数总是超过20,这说明你应该修改你对SQLServer的内存设置了。将其设置为“动态配置SQLServer的内存”,并且最大内存设置得高一些。为了达到最优,SQLServer将尽可能的获得多的内存以完成自己的工作,而不是去和其他的程序争夺内存。

Memory: Available Bytes

另一个检查SQLServer是否有足够的物理内存的方法是检查Memory Object: Available Bytes计数器。 这个值至少大于5M,否则需要添加更多的物理内存。在一个专门的SQLServer服务器上,SQLServer试图维持4-10M的自由物理内存,其余的物理内存被操作系统和SQLServer使用。当可用的物理内存接近5M或者更低时,SQLServer最可能因为缺少内存而遇到性能瓶颈。遇此情况,你需要增加物理内存以减少服务器的负荷,或者给SQLServer配置一个合适的内存。

Physical Disk: % Disk Time

这个计数器度量磁盘阵列繁忙程度(不是逻辑分区或磁盘阵列上独立的磁盘)。它提供一个对磁盘阵列繁忙程度相对较好的度量。原则上计数器% Disk Time的值应该小于55%。如果持续超过55%(在你24小时的监控周期里大约超过10分钟),说明你的SQLServer有I/O瓶颈。如果你只是偶尔看到,也不必太担心。但是,如果经常发生的话(也就是说,一个小时出现好几次),就应该着手寻找增加服务器I/O性能或者减少服务器负荷的解决之道了。一般是为磁盘阵列增加磁盘,或者更好更快的磁盘,或者给控制器卡增加缓存,或者使用不同版本的RAID,或者更换更快的控制器。

在NT4.0上使用该计数器之前,确认在NT命令提示符下输入diskperf -y,重启服务器,以便手动打开。在NT4.0下第一次必须将该计数器打开,Windows2000默认是打开的。

Physical Disk: Avg. Disk Queue Length

除了观察物理磁盘的% Disk Time计数器外,还可以用Avg. Disk Queue Length计数器。磁盘阵列中的各个磁盘的该值如果超过2(在你24小时的监控周期里大约超过10分钟),那么你的磁盘阵列存在I/O瓶颈问题。象计数器% Disk Time一样,如果只是偶尔看到,也不必太担心。但是,如果经常发生的话,就应该着手寻找增加服务器I/O性能的解决之道了。如前所述。

你需要计算这个值,因为性能监视器不知道你的磁盘阵列中有多少物理磁盘。例如,如果你有一个6个物理磁盘组成的磁盘阵列,它的Avg.
Disk Queue Length值为10,那么实际每个磁盘的值为1.66(10/6=1.66),它们都在建议值2以内。

在NT4.0上使用该计数器之前,确认在NT命令提示符下输入diskperf -y,重启服务器,以便手动打开。在NT4.0下第一次必须将该计数器打开,Windows2000默认是打开的。

一起使用这两个计数器将帮助你找出I/O瓶颈。例如,如果% Disk Time的值超过55%,Avg. Disk Queue Length计数器值超过2,服务器则存在I/O瓶颈。

Processor: % Processor Time

处理器对象: % Processor Time计数器对每一个CPU可用,并针对每一个CPU进行检测。同样对于所有的CPU也可用。这是一个观察CPU利用率的关键计数器。如果% Total Processor Time计数器的值持续超过80%(在你24小时的监控周期里大约超过10分钟),说明CPU存在瓶颈问题。如果只是偶尔发生,并且你认为对你的服务器影响不大,那没问题。如果经常发生,你应该减少服务器的负载,更换更高频率的CPU,或者增加CPU的数量或者增加CPU的2级缓存(L2 cache)。

System: Processor Queue Length

根据% Processor Time计数器,你可以监控Processor Queue Length计数器。每个CPU的该值如果持续超过2(在你24小时的监控周期里大约超过10分钟),那么你的CPU存在瓶颈问题。例如,如果你的服务器有4个CPU,Processor Queue Length计数器的值总共不应超过8。

如果Processor Queue Length计数器的值有规律的超过建议的最大值,但是CPU利用率相对不是很高,那么考虑减少SQLServer的"max worker threads"的配置值。Processor Queue Length计数器的值高的可能原因是有太多的工作线程等待处理。通过减少"maximum worker threads"的值,强迫线程池踢掉某些线程,从而使线程池得到最大的利用。

一起使用计数器Processor Queue Length和计数器% Total Process Time,你可以找到CPU瓶颈,如果都显示超过它们的建议值,可以确信存在CPU瓶颈问题。

SQL Server Buffer: Buffer Cache Hit Ratio

SQL Server Buffer中的计数器Buffer Cache Hit Ratio用来指出SQLServer从缓存中而不是磁盘中获得数据的频率。在一个OLTP程序中,该比率应该超过90%,理想值是超过99%。如果你的buffer cache hit ratio低于90%,你需要立即增加内存。如果该比率在90%和99%之间,你应该认真考虑购买更多的内存了。如果接近99%,你的SQLServer性能是比较快的了。某些情况下,如果你的数据库非常大,你不可能达到99%,即使你在服务器上配置了最大的内存。你所能做的就是尽可能的添加内存。

在OLAP程序中,由于其本身的工作原理,该比率大大减少。不管怎样,更多的内存总是能提高SQLServer的性能。

SQL Server General: User Connections

既然sqlserver的使用人数会影响它的性能,你就需要专注于sqlserver的General Statistics Object: User Connections计数器。它显示sqlserver目前连接的数量,而不是用户数。
如果该计数器超过255,那么你需要将sqlserver的"Maximum Worker Threads" 的配置值设置得比缺省值255高。如果连接的数量超过可用的线程数,那么sqlserver将共享线程,这样会影响性能。"Maximum Worker Threads"需要设置得比你服务器曾经达到的最大连接数更高。

SQLServer硬件性能监控列表

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址

性能监控列表

SQLServer硬件特征 相应的描述
Number of CPUs
CPU MHz
CPU L2 Cache Size
Physical RAM Amount
Total Amount of Available Drive Space on Server
Total Number of Physical Drives in Each Array
RAID Level of Array Used for SQL Server Databases
Hardware vs. Software RAID
Disk Fragmentation Level
Location of Operating System
Location of SQL Server Executables
Location of Swap File
Location of tempdb Database
Location of System Databases
Location of User Databases
Location of Log Files
Number of Disk Controllers in Server
Type of Disk Controllers in Server
Size of Cache in Disk Controllers in Server
Is Write Back Cache in Disk Controller On or Off?
Speed of Disk Drives
How Many Network Cards Are in Server?
What is the Speed of the Network Cards in Server?
Are the Network Cards Hard-Coded for Speed/Duplex?
Are the Network Cards Attached to a Switch?
Are All the Hardware Drivers Up-to-Date?
Is this Physical Server Dedicated to SQL Server?

在上表里输入你的值.

监控硬件是早期的重要步骤

从以前的章节里(使用性能监视器),你可以找出一些潜在的硬件性能瓶颈。这一节里,我们将查看SQLServer硬件的每一个主要组件,以帮助最优化你硬件的性能。 将分以下几个部分进行:
? CPU
? Memory
? Disk Storage
? Network Connectivity
? Misc.
作为监控的一部分,你需要完成上面的列表,这样,你就会对你的服务器无所不知了。

CPU

CPU的数量

这第一个是显而易见的,越多的CPU性能越快。SQLServer2000的标准版支持4个CPU。企业版支持最多32个CPU,具体根据操作系统而定。更多的CPU对于全面提升SQLServer的性能是很有效的。

对任何一个基于SQLServer的应用程序需要的CPU数量进行估算是很困难的。这是因为每个应用程序的工作都是不同的,并且它们的使用也不同。有经验的DBA总是对应用程序需要什么样的CPU有个大概的了解,却很难真正知道需要什么样的CPU,直到在真实条件下测试了服务器的配置。
由于选择合适的CPU的数量是困难的,所以你可以考虑下面的原则:
? 尽可能的购买更多CPU数量的服务器。
? 如果你做不到,那么至少要购买一个能扩展CPU数量的服务器。几乎所以的SQLServer在工作量增加时都需要更多的动力。
这是一些潜在的假设:
? SQLServer将仅仅用来运行一个同时不超过5个用户的财务应用程序,并且你预期未来两年不会改变。如果是这样,单CPU的服务器就足够用了。如果预期用户数量在不久会增加的话,那么你需要考虑购买一个单CPU的,并且拥有可扩展一个CPU数量的服务器以备不时之需。
? SQLServer用来运行一个内部的写程序,这个程序不仅仅包括OLTP,而且需要支持繁重的报表需求。预期用户同时不会超过25个。如果是这样,你需要考虑一个双CPU的服务器,但是它应该可以扩展到4个CPU。“繁重的报表需求”的真正含义是很难预计的。我曾经看到一些相当简单,但是不好的写报表,占用了服务器全部的CPU。
? SQLServer运行一个目前用户为100到150之间的ERP包。对于象这样的“重型”程序,询问推荐的硬件配置。因为他们已经对他们的产品需要的CPU配置有了一个很好的建议。
我能提供一些其他的例子,但是通过这些我发现:正确预计基于SQLServer的一个特殊的应用程序的CPU的数量是很困难的。你通常应该购买一个比你认为要大的系统,因为在许多情况下,一个应用程序的使用需求经常是被低估了的。现在购买一个有多个CPU的大服务器来长期使用也不是很昂贵了,总比你在6到12个月后由于当初的低估不得不重新替换你整个服务器要划算得多。

CPU速度

象CPU的数量一样,需要的CPU的速度 也是很难估计的。一般说来,尽量购买最快的CPU。购买速度快的总是好于速度慢的。

CPU 2级缓存

我曾经遇到一个比较普遍的问题:购买2级缓存较小的便宜的CPU好呢,还是购买2级缓存较大的昂贵的至强CPU好?事实上,在购买2级缓存较小的更快的芯片和购买较大2级缓存的芯片上做出决定是很困难的。这里有一些规则:
? 如果你仅有1、2个CPU,那么尽量买最快的,其次才考虑2级缓存。如果你一定要选择2级缓存大小的话,尽量选择较大的。
? 但是,如果你有4个或更多的CPU,那么你需要较大2级缓存的CPU,即使它们的速度不太高。这是因为对于一个有4个或更多CPU的服务器来说,要想尽量让SQLServer运行良好的话,2级缓存一定要大,否则将浪费额外的CPU。
CPU监控列表

既然本文是关于你SQLServer目前CPU性能的一个监控,那么你现在应该关注你目前的服务器是否存在CPU瓶颈。正如在《使用性能监视器找出硬件瓶颈》一文所讨论的那样,你可以使用性能监视器帮助你找到硬件瓶颈。

如果你CPU目前没有瓶颈问题,那么你可以忽略下一部分关于memory的讨论。但如果你的服务器目前存在CPU瓶颈,并且是主要的性能问题,那么你可以选择以下的方法去解决瓶颈:
? 减少服务器的负荷。可以通过减少用户数量、调优查询、调优索引、除去在服务器上运行的不必要的程序来达到目的。另外如果你的产品服务器上还运行有关于报表的程序,将其移到一个专门为报表做的服务器上。
? 如果CPU瓶颈是由于缺少服务器内存引起的,请添加更多的内存。这是一个普遍的问题。
? 如果你目前的服务器有更多的CPU插槽,那么请添加更多的CPU。
? 如果可以的话,用更快的CPU升级你的服务器。
? 购买一个新的有更多更快CPU的服务器。
不幸的是,这些方法在处理CPU瓶颈时也不是轻而易举的,当然除非你们公司有足够的钱。作为一个DBA来说,你可能唯一能做的就是“减少服务器的负荷”这一项了。

内存

在讨论完CPU后,现在开始讨论内存,不要认为它不象CPU那么重要。事实上,内存可能是任何SQLServer服务器最重要的硬件部分,它比其他硬件更能影响SQLServer的性能。
当我们讨论内存的时候,一般指的是物理内存,而不是虚拟内存。SQLServer不是设计来用虚拟内存的,尽管它也能用。 并非联合使用操作系统的物理内存和虚拟内存,SQLServer总是尽可能的使用物理内存。这主要是为了提高速度。访问内存中的数据总是比访问磁盘上的快得多。

SQLServer不能总是把数据放在内存(SQLServer缓存)中,它也访问磁盘,就像操作系统管理虚拟内存一样。但SQLServer的“缓存”机制比操作系统的虚拟内存更快更诡异。

快速的知道SQLServer是否有足够内存的方法是检查SQLServer的缓存命中率(在《使用performance Monitor找出硬件瓶颈》一文有过讨论)。如果这个计数器为99%或者更高,说明有足够的内存。如果这个计数器在90%与99%之间并且你对性能比较乐观的话,那么你的SQLServer可能有足够的内存,但是如果你不满意服务器性能的话,则需要添加内存了。
如果这个计数器少于90%,关键在于性能无法被接受(如果运行的是OLAP,少于90%通常也没问题),所以需要添加更多的内存。 SQLServer的物理内存的理想值应该超过服务器上最大数据库的大小。这总是不可能的,因为许多数据库是非常大的。如果你正在计算
SQLServer的大小,并且有足够的预算,那么尽量去购买能容纳整个数据库大小的物理内存。假定你的数据库是4G或者更小,那么这通常不会成太大的问题。但是如果你的数据库更大(或者预期会超过4G),那么你可能容易地提供超过4G的内存。SQLServer2000企业版支持高达64G的内存,没有太多的服务器支持这么大的内存。

即使SQLServer的缓存不能容纳整个数据库,SQLServer仍然能快速的获取数据。99%的缓存命中率意味着SQLServer需要的数据99%的时间都是在缓存中的,性能非常快。例如,我管理一个30G的数据库,但是服务器仅有4G的内存,而缓存命中率总是高于99.6%。这意味着大多数情况下用户没有同时访问数据库里所有的数据,仅仅一小部分而已,SQLServer也能将经常访问的数据始终放在缓存中,所以99%的请求在这种情况下能迅速完成,即使服务器的内存少于数据库的大小。

那么,要点是什么呢?如果你的缓存命中率少于90%,那么认真的考虑添加更多的内存了。

磁盘存储器

在内存之后,磁盘存储器也是经常影响SQLServer性能的的最重要的因素。 它也是一个复杂的话题。在这部分,我将专注于磁盘存储器影响性能最容易的地方。 服务器上可用磁盘空间的总量 所有的磁盘阵列至少要20%的可用空间,这样对性能影响才不是很大。这是因为NTFS(假定你使用的是该磁盘格式)需要额外的空间才能工作得更好。如果没有可用空间,那么NTFS不能运行并且性能会降低。它也会导致更多的磁盘碎片,因为服务器读写数据更加可能。
查看你SQLServer的每一块物理磁盘,检查一下是否有至少20%或者更多的可用空间。如果没有,考虑以下方法:
? 删除磁盘上任何不需要的数据(清空回收站、临时文件、setup文件等等)
? 删除一些数据以留出更多的空间
? 添加更多的磁盘空间
每一个磁盘阵列的物理磁盘数量 一个磁盘阵列通常由2个或者更多的物理磁盘作为一个单一的单元一起工作。例如RAID5阵列也许有4个物理磁盘。那么为什么了解你SQLServer的一个或多个磁盘阵列有多少个物理磁盘是很重要的呢?
除镜像磁盘(两个物理磁盘一起工作)外,磁盘阵列有越多的物理磁盘,对于磁盘阵列的读写就越快。 例如,假如想买一个新的做RAID5的至少有100M可用空间的SQLServer服务器,并要求提供以下两种不同的磁盘阵列配置:
? 4个36G的磁盘(可用空间为108G)
? 7个18G的磁盘(可用空间为108G)
按照要求这两者都符合标准。但是哪一种磁盘阵列能提供更快的读写性能呢?答案是第二种,即7个18G的磁盘。为什么呢?
一般说来,磁盘阵列中磁盘越多,可用来读写的磁盘头就越多。例如,SCSI磁盘可以同时读和写数据。所以一个磁盘阵列有越多的物理磁盘,该磁盘阵列的读写速度就越快。阵列中的每个磁盘分担一部分工作量,磁盘越多越好。这儿有一个限制,依赖于磁盘控制器,但通常说来,越多越好。 那么这对你来说意味着什么呢?在你查看了你的服务器有多少磁盘阵列、每个磁盘阵列有多少磁盘后,重新配置目前的磁盘阵列以更好的利用
是不是可行呢?
例如,假定你目前的服务器有2个磁盘阵列用来存储用户数据库。每一个是3个18G的磁盘组成的RAID5阵列。这种情况下,将两个阵列重新配置成一个由6个18G的磁盘组成的阵列会更好。这不仅仅提供了更快的I/O,而且也能获得18G的的磁盘空间。
仔细检查你目前的配置,你可以改变很多,也许不可以。但是如果你可以改变的话,你将在你改变之后立即从中得到好处。 SQLServer数据库通常使用的磁盘阵列的RAID级 或许你已经知道,磁盘阵列有不同类型的配置,称作RAID级别。每一级别都有各自的拥护者和反对者。下面是一些经常使用的RAID级别的简单总结,了解后你就知道在你的SQLServer怎样更好的使用它们:
RAID 1
? 操作系统(包括虚拟内存)和SQLServer最理想的是运行在RAID1磁盘阵列上。也有人将虚拟内存运行在一个独立的RAID1磁盘阵列上,但是我对这样做是否能提供虚拟内存性能表示怀疑,在一个好的配置的服务器上,那不是问题。
? 如果你的SQLServer数据库非常小,所有的数据都能在一个磁盘下存储,那么请为你的数据库文件存储考虑RAID1级别。
? 理想地,每一个独立的事务日志应该运行在一个独立的RAID1磁盘阵列上。这是因为事务日志在不断的读写,通过放在独立的磁盘阵列上,由于连续的磁盘I/O不和更慢的随机的磁盘I/O混合使用,从而使性能得到提升。
RAID 5
? 尽管这是比较流行的RAID级别,对于最优化SQLServer的I/O性能还不是最好的选择。如果数据库的写操作比例超过10%,大多数OLAP数据库都是这样,写性能会降低,从而伤害整个SQLServer的I/O性能。RAID5最好用于只读或者大部分时候是读的数据库。在微软的测试发现RAID5比RAID10几乎要慢50%。
RAID 10
? RAID10为SQLServer数据库提供了最好的性能,尽管它是最贵的。数据库的写操作越多,使用RAID10更重要。
? RAID10阵列对于事务日志也是不错的选择,假定它只用来存储单个事务日志。
更可能的是,你目前的SQLServer配置不符合上面的建议。某些情况下,你需要更改你目前的配置以尽量符合上面的建议,但是大多数情况下,你可能不得不忍受直到有新的预算去买新的服务器和磁盘阵列。
如果你只能选择上面的一个 建议的话,我建议你使用RAID10。这将最大化你SQLServer的I/O性能。

硬件RAID vs. 软件RAID

可以通过硬件或者软件(通过操作系统)实现RAID。不要使用软件RAID,会很慢,总是使用硬件RAID,这是不争的事实。

磁盘碎片

如果你在一个崭新的磁盘阵列上创建了一个新的数据库,数据库文件和事务日志文件会是一个连续的文件。但如果数据库文件或事务日志文件
在创建时指定的最大容量里增长(通常都会超过该容量),随着时间的推移文件可能会产生碎片。文件碎片(磁盘阵列上分散的许多块文件)
引起你的磁盘阵列在读写数据时变慢,从而影响磁盘I/O的性能。
作为性能监控的一部分,你需要了解你的SQLServer数据库和事务日志是怎样产生碎片的。如果你使用的是Windows2000或者2003,你可以使用内建的碎片整理工具去分析文件变成碎片的严重程度。如果你运行的是NT4.0,那么你可以借助第三方工具如DisKeeper来进行分析。 如果分析结果需要进行碎片整理,则进行。不幸的是,整理SQLServer数据库和事务日志的碎片不总是一件容易的事。运行着的文件,象在 SQLServer上运行的数据库和事务日志文件,不总是能进行碎片整理。例如,内建的碎片整理工具不能整理SQLServer的MDF和LDF文件,但是DisKeeper8.0在大多数情况下可以,而不是全部情况都可以。这意味着在某些情况下,为了整理SQLServer的MDF和LDF文件的碎片,你不得不使SQLServer离线。依赖文件整理的方式、文件的大小、这可能需要花费很多小时。
你真有必要对数据库文件进行碎片整理吗?如果你的I/O性能目前比较适中,那么你不需要进行碎片整理。但是如果你的I/O性能是个瓶颈的话 ,碎片整理是一个提升性能的便捷之道,尽管大多数情况下会花费一些时间。
理想地,你应该周期性的整理你的SQLServer数据库和事务日志碎片。这样,你能确信没有I/O性能问题。

操作系统

为了最佳性能,操作系统文件和SQLServer数据库文件(MDF、LDF文件)不要放在一个磁盘阵列上。另外,操作系统文件应该放在一个支持 RAID1、5或10的磁盘阵列上。
和大多数人一样,通常我也是在服务器的C盘上安装操作系统。并且为了容错和最好的性能将C盘配置为RAID1的镜像磁盘。 在大多数情况下, 只要你不把操作系统和SQLServer数据文件放在同一个磁盘阵列上,你在服务器上处理操作系统文件就会获得很大的性能。

SQLServer程序

象操作系统文件一样,SQLServer程序也不是很挑剔,只要不和SQLServer数据文件放在同一个磁盘阵列上就行。和操作系统文件一起,我通常将SQLServer程序放在被配置为RAID1镜像的C盘。 如果你在配置SQLServer7.0的群集,那么SQLServer程序不能安装在C盘,必须安装在共享磁盘阵列上。不幸的是这经常和SQLServer的数据文件是同一个磁盘阵列,除非你有足够的钱仅仅为提升SQLServer程序性能而购买一个独立的独立磁盘阵列。当性能被与数据库文件在同一磁盘阵列上的SQLServer程序轻微影响时,获得容错能力也是一个不太坏的折中方案。另一方面,升级到SQLServer2000群集是一个不错的选择。如果你在配置SQLServer2000群集,那么SQLServer程序必须放在本地磁盘上,而不是共享磁盘阵列上,所以性能不成问题。

虚拟内存

如果你有一台SQLServer的专用服务器,并且SQLServer的内存设置为动态(缺省),那么虚拟内存将很少用到。这是因为SQLServer通常不会太多的使用它。因此,虚拟内存放在任何一个特定的位置不是关键,除了不要放在SQLServer数据文件的同一磁盘阵列上。 通常,我把虚拟内存放在操作系统和SQLServer程序的同一磁盘阵列上,正如我前面所述,它是一个支持RAID1、RAID5、RAID10的磁盘阵列,通常是C盘,这使管理员更容易管理。 如果不是SQLServer专用服务器,除了SQLServer外还运行了其他程序,由于其他程序的原因,虚拟内存可能会有问题,为了获得更好的性能,你需要考虑将虚拟内存配置到一个专用的列上。然而,更好的方法是使用一台SQLServer的专用服务器。

tempdb数据库

如果tempdb数据库的使用比较繁重,为了提高磁盘I/O性能,考虑将它移到一个RAID1或者RAID10的独立磁盘阵列上。不要使用RAID5,因为对于写操作是慢的,如使用,会对tempdb产生副作用。如果不能提供独立的磁盘阵列,你有不想将它与数据库文件放在同一个磁盘阵列上,可以考虑放在操作系统的那个磁盘上,这将帮助减少I/O的争夺以提高性能。 如果应用程序非常多的使用tempdb数据库,从而引起文件增长超过它的缺省大小,那么你需要将tempdb的缺省大小增加到最近你的应用程序实际使用的tempdb的大小。这是因为每次SQLServer服务重新启动后,tempdb文件都会按照缺省值重建。当tempdb增长时会花费一些性能资源。通过在SQLServer重新启动时给tempdb分配一个合适的大小,你不必担心在使用时超过这个大小了。 另外,在tempdb数据库里繁重的操作会降低应用程序的性能。尤其是在创建一个或多个大的临时表去查询或者做联接时。为了加速这些查询,确信tempdb数据库的AUTOSTATS(自动更新统计信息)选项已打开,并且在这些临时表上创建一个或多个索引。大多数情况下,你将发现这能充分加速你的应用程序。但象许多性能建议一样,测试看看是否有实际的帮助。

系统数据库

系统数据库(master、msdb、model)没有大量的读写操作,所以把它们和你的SQLServer数据文件放在同一磁盘阵列上通常也没有性能问题。仅仅一种情况除外,就是有成百上千用户的大数据库。这种情况下,把系统数据库放在一个独立的磁盘阵列上以稍微提高I/O性能。

用户数据库

为了最佳性能,用户数据库文件放在它们自己的磁盘阵列上(RAID1、5或10),和所以的其他数据库文件,包括日志文件分开。如果再同一个SQLServer上有多个大数据库的话,考虑为每一个数据库文件分配一个独立的磁盘阵列以减少I/O争夺。

日志文件

理想地,每一个日志文件都应该有它自己独立的磁盘阵列(RAID1或10,注意RAID5会降低事务日志写操作的性能,低于你的预期)。原因是大多数时候,事务日志在连续的写操作,如果磁盘阵列能连续的写数据的话(不必中断去进行其他的读写操作),那么连续写会很快。但是如果你的磁盘阵列不能连续的写的话,由于它不得不随机的执行其他读写操作,连续写就得不到执行,性能就降低了。 当然,为每一个日志文件提供一个独立的磁盘阵列是很昂贵的。那么至少将所有的日志文件放在一个磁盘阵列上(RAID1或RAID10),而不要与数据库文件放在一个磁盘阵列上。连续的写性能尽管没有为每个日志文件提供一个独立的磁盘阵列那样好,它仍然比试图与数据库文件一起竞争磁盘I/O的性能好的多。

服务器上磁盘控制器的数量

单个的磁盘控制器,不论它是SCSI还是fibre,都有一个最大的吞吐量的限制。因此,你需要让磁盘控制器的数量与你期望的数据吞吐量相匹配。每个控制器都是不同的,我无法推荐一个明确的解决方案,但最少应该有2个磁盘控制器。一个用于非硬盘设备如CD-ROM、备份设备等等。另一个用于硬盘。目的是不要将快的和慢的设备放在同一个控制器上。 经常使用的一个较好的方案是:一个控制器为非硬盘设备,一个为RAID1的本地硬盘,第三个(有时更多)用于存放数据库文件和日志文件的磁盘阵列。确保不要为控制器捆绑超过它能处理的更多的磁盘,那样当它工作的时候,会降低性能。

服务器上磁盘控制器的类型

总是尽可能的购买最快的磁盘控制器,如果你想要最好的SQLServer性能的话。也许你知道,不同的磁盘控制器有不同的性能特征。例如,对于SCSI类型来说,就有Wide SCSI, Narrow SCSI, Ultra SCSI等不同的类型。光纤连接在更小的层次上,也和上述一样,不同的磁盘控制器有不同的性能特点。 由于控制器的种类很多,我不能做任何明确的建议。通常硬件厂商会提供不同的模型供选择。逐一咨询各自的利弊,选择最适合你的那一款。

服务器上磁盘控制器的缓存大小

当你购买磁盘控制器的时候,也要考虑它缓存的大小。一些磁盘控制器允许添加额外的磁盘缓存。通常你要购买的磁盘缓存应和控制器能容纳 的缓存一样多。SQLServer对I/O是非常强烈的,所以去做任何可以提高I/O性能的事,象购买一个大的磁盘缓存,将帮助很大的改善性能。

磁盘控制器上的写回缓存是开还是关?

磁盘控制器上的磁盘缓存提供两个方法去加速访问。一个是为了读,一个是为了写。这其中最重要的是读,这是大多数SQLServer数据库花费磁盘I/O时间的地方。另一方面,一个写回缓存是用来加速写操作的,而写相对于读来说通常不是很多。不幸的是,大多数情况下,SQLServer采取写回缓存不打开,因此,写回缓存在大多数磁盘控制器上是被关掉的。如果你不那样,在一定环境下,在SQLServer写数据后(一旦它写完数据,它就会认为是正确地写的),可能会取得一些脏数据,但是由于某些原因(例如电力不够),写回缓存不会把数据写到磁盘上。 一些控制器提供了备份电池以防止这样的问题,但它们不总是能如预期的那样工作。个人认为,宁愿要正确的数据虽然写慢一点,也不要错误 的数据,尽管那样写更快。 换句话说,我建议你关掉磁盘控制器上的写回缓存,虽然那样会对写性能有一些非常小的影响。

磁盘转速

磁盘阵列里的磁盘有不同的转速。 正如你所想,为了最佳的性能,总是购买最快的磁盘。通常是15000转或更快。另外,不要将不同转速的磁盘放在同一个磁盘阵列里,那样会影响性能。

服务器上的网卡数量是多少?

幸运的是, 网络流量通常不会称为SQLServer的瓶颈。单个网卡总是足够用。但是如果你发现网络流量成问题了(你已经有成百上千个用户),那么添加多个网卡总是正确的,这能提高性能。另外,两个或者更多的网卡能增加冗余,减少宕机时间。

网卡速度是多少?

至少应使用100M的网卡,10M的不能满足你需要的带宽。如果一个或者更多的100M的网卡不能满足,考虑用G级的网卡。事实上,你可能需要完全地跳过100M的网卡而仅仅用G级的网卡代替。使用更快的网卡不会增加网络流量,它仅仅允许更多的流量通过,轮流的允许你的服务器在适宜的性能下运行。

网卡硬编码是Speed/Duplex的吗?

如果你的SQLServer有两个10/100或者10/100/1000的网卡,假定是自动识别网卡速度并设置为适合的,别相信那个能正常的工作。网卡通常不能正确的自识别,总是设置一个小于最佳速度的值或者duplex设置,这样会影响网络性能。你需要做的是手工设置卡的速度和duplex设置,以便你能确认它已经正确的设置了。

网卡是连在交换机上的吗?

在一个大的数据中心这是显而易见的,但是对于小的机构来说,使用一个Hub来连接服务器。要是那样,请认真考虑用适当的交换机替换掉Hub,用可能最高的性能去配置交换机,例如100M并且全双工通信。将Hub替换为交换机后在网络性能上会有一个戏剧性的不同。

所有硬件的驱动都是最新的吗?

诚然,这是一个烦人的话题,但它比你认为的更重要。最大的性能消耗之一是有Bug的驱动(会引起一些奇怪的不常见的问题),无论它们是在磁盘控制器中还是网卡中,或者别的地方。通过使用最新的驱动,你有可能得到更好更快的性能的驱动,从而提高SQLServer的性能。 你应该定期的检查你的硬件是否有新的驱动可用,当你有时间的时候去安装它们。我本人曾经将一个老的有很多bug的驱动更新后是性能得到了彻底的根本提升。

SQLServer服务器是专用的吗?
前面我间接提到过,SQLServer应该运行在一个专用的服务器上,而不是和其他应用程序、软件共享一个服务器。当你将SQLServer和其他软件共享时,你迫使SQLServer去争取物理资源,这样调优SQLServer性能就更加困难。有很多次我在查找SQLServer性能低下的原因时都发现是另一个和SQLServer运行在同一台服务器上的应用程序的缘故。
性能监控列表
操作系统性能相关项 你的配置
操作系统版本
磁盘分区格式是NTFS5.0吗?
NTFS数据文件加密压缩是否关闭?
SP是否最新?
服务器是否有最新的微软认证的硬件驱动?
服务器是否是独立的服务器?
应用程序响应是否设置为为后台访问最优化性能?
安全审计是否打开?
服务器的虚拟内存文件PAGEFILE.SYS有多大?
不必要的服务是否关闭?
所有不必要的网络协议是否关闭?
是否使用杀毒软件?

在上表输入你的结果.

配置Windows服务器是很容易的,但却很关键

这一部分性能监控将着重于基本的操作系统,为了获得最佳的SQLServer性能怎样去优化操作系统。 和SQLServer一样,Windows服务器也是自我调优的。但我们也可以象调优SQLServer一样,通过调优操作系统来提升性能。在提升操作系统性能的同时,SQLServer的性能也得到相应的提升。

是否选择了性能最佳的操作系统?

SQLServer可以运行在NT4.0,win2000和Win2003上,这里将讨论作为最新版本操作系统的Win2003。对于NT4.0和Win2000,将在其他的文章里进行介绍。 如果你想发挥SQLServer最佳的性能,你需要运行在Win2003上,它比2000和4.0提供了更多的性能改善,包括:
? 更好利用Intel超线程CPU的能力。
? 使用Intel芯片最多可支持32个CPU和64G的内存,使用Itanium芯片最多可支持64个CPU和512G的内存。
? I/O通道和磁盘I/O性能得到充分提升的同时,减少了大量的I/O请求所需要的CPU资源。
如果你还没升级到2003,尽快升级吧。它会更快更容易的提升SQLServer的性能。

磁盘分区格式是NTFS 5.0吗?

如果你的服务器是新的,Win2000或Win2003也是最近安装的,呢帽所有的磁盘都是使用NTFS5.0格式化的。但是,如果服务器很老,且运行的是NT4.0,磁盘在升级到Win2000或2003后没有重新格式化,磁盘格式可能还是NTFS4.0。 虽然NTFS5.0和4.0没有太多的不同,但升级也是值得的。NTFS5.0包括一些新的增强性能,这意味着在找文件时会访问更少的磁盘,通常磁盘读会更快。在Win2000和2003以前,一些DBA将日志文件所在的磁盘或者磁盘阵列用FAT格式化,因为它比NTFS4.0稍微有些性能提升。在NTFS5.0下就不再是这样了,所以所有SQLServer的磁盘都用NTFS5.0格式化以达到最佳性能。 如果目前你在Win2000下用NTFS4.0格式运行你的SQLServer,对于你来说转到NTFS5.0也许是困难的。如果真是这样,我建议你不必担心,性能也不会有太大的伤害。但是如果你将NT4.0升级到2000,你需要用NTFS5.0重新格式化你的磁盘以利用每一个在你服务器上能发现的细微的性能提升。

NTFS数据文件加密压缩是否关闭?

2000下的NTFS5.0支持文件加密和压缩,在新安装的Win2000或2003服务器上这两个值缺省是关闭的。这些特征确实在有限的环境下提供一些好处,却不能给SQLServer提供任何好处。事实上,使用一个或两者都用会极大地伤害性能。 正如你所知,SQLServer对I/O很敏感,任何增加磁盘I/O开销都会影响SQLServer的性能。文件加密和压缩显然增加了磁盘I/O开销,数据文件不论忙闲都得被维护。所以对SQLServer文件不论是压缩还是加密,都将极大地影响性能。 如果你作为DBA接手一个已经存在的SQLServer,你对它又不太熟悉,检查看看是否有人错误地打开了任何一个选项。如果是,关闭它,对所有的服务器用户来说,他们会认为你是性能高手。

SP是否最新?

每一个SP都有一个或更多的性能提升。因为微软进行了优化,或者修改了以前影响性能的Bug。 微软发布sp的时候不要安装,等测试完成后再安装。

服务器是否有微软最新认证的硬件驱动?

在很多场合,我在Win2000和2003上都看到引起的性能问题的老的有Bug的硬件驱动。大多数情况下和磁盘或者网络驱动有关。 你应该周期性的检查你的服务器是否有最新的微软认证的硬件驱动。可以去硬件厂商的网站查看,或者通过微软的升级服务。大多数情况下,你在硬件厂商的网站上能找到新的驱动,但还没有经过微软的认证。我建议你等待微软的认证版本。尽管提升性能很重要,但软件的稳定性也很重要。

Windows2000服务器是否配置为独立的服务器?

Win2000或2003可以配置为独立的服务器或者域控制器。为了最佳的性能,SQLServer应该运行在一个独立的服务器上。这是因为域控制器占用很多服务器资源,SQLServer的性能就会下降。

应用程序响应是否设置为为后台服务最优化性能?

在Win2000里,控制面板里的系统图标的高级标签下,单击性能选项,你可配置一个叫作“应用程序响应”的设置。可以从“应用程序”和“后台服务”中选择一个去优化性能。为了提升SQLServer性能,你应该选择“后台服务”,这样告诉操作系统你需要优先处理后台程序如SQLServer而不是前台程序。 在Win2003里,控制面板里的系统图标的高级标签下,单击性能下的设置按钮,单击高级标签。在这里,你可以象在2000里那样设置即可。
你也可以在这儿更改内存设置为程序和系统缓存二者之一。为了得到最佳的SQLServer性能,选择程序。这是告诉操作系统给程序如SQLServer而不是系统缓存分配更多的内存。 做完这些更改,可能需要重启服务器。

安全审计是否打开?

事实上,Win2000和2003能审计服务器上的任何一个活动。许多安全审计确实是关闭的。为了最好的性能,不要打开另外的审计,否则会增加I/O开销,和SQLServer竞争I/O。当然,如果你不得不打开,尽可能的限制以尽量减少对性能的影响。

服务器虚拟内存文件PAGEFILE.SYS有多大?

微软建议PAGEFILE.SYS文件设置为物理内存的1.5倍。正确的数量需要依赖于运行的SQLServer。例如,如果你在运行全文索引服务,微软建议你设置为物理内存的3倍。 微软的建议是一个理想值,决定PAGEFILE.SYS大小的最佳途径是使用性能监视器监控Page File对象的% Usage计数器的值是多少,然后重新设置PAGEFILE.SYS的大小,最小应该稍微大于性能监视器记录的实际值,最大值比最小值大50M。 在Win2000中通过右击我的电脑,选择属性,单击高级标签,单击性能选项单击虚拟内存下的更改按钮,可以设置PAGEFILE.SYS的大小。更改后,需要重启生效。 在Win2003中,通过控制面板的系统图标的高级标签,单击性能下的设置按钮,然后单击高级标签,单击虚拟内存下的更改按钮,可以设置PAGEFILE.SYS的大小。

不必要的服务是否关闭?

为了最佳性能,关闭Win2000或2003系统任何一个不需要的服务。这既节约了内存也节约了CPU,从而全面提升SQLServer性能。 下面是一些操作系统服务(不全),通常被认为是不重要可关闭的。其中一些服务也可不必安装,另外一些设置为“禁止”或“手动启动”, 这依赖于你服务器的安装和配置。一些服务仅仅在需要时启动,所以设置为手动启动,当不再需要的时候关闭。
? Alerter
? Application Management
? Clipbook
? Distributed Link Tracking Server
? Fax Service
? File Replication
? FTP Service
? Indexing Service
? Internet Connection Sharing
? Intersite Messaging
? Kerberos Key Distribution Center
? License Logging Service
? Logical Disk Manager Administrative Service
? Messenger
? Microsoft Search
? NetMeeting Remote Desktop Sharing
? Network DDE
? Network DDE DSDM
? Print Spooler Service (if you won't be printing from this server)
? QoS RSVP
? Remote Access Auto Connection Manager
? Remote Procedure Call (RPC) Locator
? Routing and Remote Access
? RunAsService
? Smart Card
? Smart Card Helper
? SMTP Service
? Telnet
? Utility Manager
? Windows Installer
? World Wide Web Service
通常,我总是关闭这些服务,将它们的启动类型设置为手动。当然如果你需要任一服务,你不必关闭它。

所有不必要的网络协议是否关闭?

SQLServer通常只需要TCP/IP协议 。移除SQLServer服务器上其他不必要的网络协议可以通过减少网络流量来减少负荷。

是否使用杀毒软件?

实时的杀毒软件占去大量的SQLServer资源,在SQLServer服务器上不建议用,尤其是在集群上。

如果你担心病毒的话,你可以每天在不用SQLServer时进行远程扫描。

SQLServer配置项监控列表

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址


性能监控列表
SQL Server配置设置 是否高级设置? 是否需要重启? 缺省值 当前值
affinity mask Yes Yes 0
awe enabled Yes Yes 0
cost threshold for parallelism Yes No 5
cursor threshold Yes No -1
fill factor (%) Yes Yes 0
index create memory (KB) Yes No 0
lightweight pooling Yes Yes 0
locks Yes Yes 0
max degree of parallelism Yes No 0
max server memory (MB) Yes No 2147483647
max text repl size (B) No No 65536
max worker threads Yes Yes 255
min memory per query (KB) Yes No 1024
min server memory (MB) Yes No 0
nested triggers No No 1
network packet size (B) Yes No 4096
open objects Yes Yes 0
priority boost Yes Yes 0
query governor cost limit Yes No 0
query wait (s) Yes No -1
recovery interval (m) Yes No 0
scan for startup procs Yes No 0
set working set size Yes Yes 0
user connections Yes Yes 0


在上表里输入你的结果.

大多数SQLServer配置设置不必更改

这一节,我们将讨论与性能相关的SQLServer配置设置。可以使用企业管理器或者系统过程SP_CONFIGURE对这些配置进行设置。

正如标题所说,大多数情况下,你不应该修改SQLServer的这些缺省配置。这是因为大部分缺省值能为大多数SQLServer提供最优的性能。糟糕的是,如果你不知道改变这些值是什么意思的话,反而可能会影响SQLServer的性能。

如果你是第一次处理SQLServer,首先应该了解各个配置的含义。然后一个一个的更改,跟缺省值比较看有什么变化。一旦你确定改变一个配置的值了,接下来你就应该知道为什么要改变它。如果你找不到原因,或者找到了但原因不可信,那么你需要修改回缺省值。接下来象前面那样去配置每一个值,以使其达到最合适。

本文着重于SQLServer2000,不过大多数建议也适合SQLServer7.0。在SQLServer7.0下试图采用这些建议前,你需要从SQLServer7.0的帮助文档中确认。

SQLServer2000中共有36个不同的配置 ,这里仅仅着重于23个与性能有关的关键配置。

现在开始

开始查看SQLServer的配置的最简单的方法是对你的每个服务器,在查询分析器里运行命令SP_CONFIGURE。

你会看到类似下面的一个表:

name minimum maximum config_value run_value
----------------------------------- ----------- ----------- ------------ ----------
affinity mask -2147483648 2147483647 0 0
allow updates 0 1 0 0
awe enabled 0 1 0 0
c2 audit mode 0 1 0 0
cost threshold for parallelism 0 32767 5 5
cursor threshold -1 2147483647 -1 -1
default full-text language 0 2147483647 1033 1033
default language 0 9999 0 0
fill factor (%) 0 100 0 0
index create memory (KB) 704 2147483647 0 0
lightweight pooling 0 1 0 0
locks 5000 2147483647 0 0
max degree of parallelism 0 32 1 1
max server memory (MB) 4 2147483647 2147483647 2147483647
max text repl size (B) 0 2147483647 65536 65536
max worker threads 32 32767 255 255
media retention 0 365 0 0
min memory per query (KB) 512 2147483647 1024 1024
min server memory (MB) 0 2147483647 0 0
nested triggers 0 1 1 1
network packet size (B) 512 65536 4096 4096
open objects 0 2147483647 0 0
priority boost 0 1 0 0
query governor cost limit 0 2147483647 0 0
query wait (s) -1 2147483647 -1 -1
recovery interval (min) 0 32767 0 0
remote access 0 1 1 1
remote login timeout (s) 0 2147483647 5 5
remote proc trans 0 1 0 0
remote query timeout (s) 0 2147483647 600 600
scan for startup procs 0 1 0 0
set working set size 0 1 0 0
show advanced options 0 1 1 1
two digit year cutoff 1753 9999 2049 2049
user connections 0 32767 0 0
user options 0 32767 0 0

第一列“Name”是SQLServer配置设置的名称,第二列“minimum”可用的最小配置,第三列“maximum”是可用的最大配置,第四列“config_value”是该项的设置值(但可能是也可能不是SQLServer目前的实际运行值,有些设置需要重启SQLServer才有效,有些需要RECONFIGURE WITH OVERRIDE选项运行后才有效),最后一列“run_value”是目前有效的设置值。如果你在最后一次重启SQLServer后没有更改任何值的话,最后两列的值将是相同的。

不幸的是,这些配置的缺省值在运行SP_CONFIGURE没有列出来。为了方便,本文已列出它们的缺省值。(见最开始的那个表)

怎样更改SQLServer配置设置

SQLServer的这些配置大多数而不是全部可以在企业管理器中进行修改。但是更简单的一个途径是运行SP_CONFIGURE命令去更改这些值,象这样:

SP_CONFIGURE ['configuration name'], [configuration setting value]
GO
RECONFIGURE WITH OVERRIDE
GO

注:

configuration name指的是配置设置的名称(见上表)。注意名称必须用单引号括起来(或者是双引号,这依赖于查询分析器的配置)。configuration setting value指的是该配置的具体的数值(不用单引号)。

一旦运行完SP_CONFIGURE命令,你必须做下面的工作,要么运行RECONFIGURE选项(用于常规设置),要么运行RECONFIGURE WITH OVERRIDE选项(用于那些如果你犯错了就会给你带来麻烦的设置),否则你的更改不会生效。与其试图记住什么时候需要用RECONFIGURE,还不如记住任何时候RECONFIGRE WITH OVERRIDE都适用来得容易,RECONFIGRE WITH OVERRIDE适合于所以的配置。如果你用企业管理器更改了设置,RECONFIGURE WITH OVERRIDE会自动的执行,所以你不必再去执行。

一旦你更改完毕,大多数的设置而不是全部会立即生效,有一些值在运行RECONFIGURE后也不会生效,除非重启SQLServer的服务。

在完成本文之前,你应该知道:许多配置属于“advanced”设置。在使用SP_CONFIGURE命令更改这些值之前,你必须首先更改SQLServer配置中的一项,然后才能去更改那些配置。命令如下:

SP_CONFIGURE 'show advanced options', 1
GO
RECONFIGURE
GO

仅在你运行上面的代码后你才能运行SP_CONFIGURE来更改那些高级的SQLServer配置。

现在你知道怎样更改这些SQLServer配置选项了,下面看看它们和性能的关系。

Affinity Mask

当SQLServer在Windows服务器下运行时,一个SQLServer线程可以在CPU之间迁移。这个特征允许SQLServer同时运行多个线程,这样服务器可以在多个CPU之间进行更好的负载均衡。每当一个线程从一个CPU移到另一个CPU,处理器缓存都要重载,大多数情况下会影响性能。

在多于4个CPU的负荷繁重的服务器里,通过特定处理器运行特定的线程来提升性能。这会减少处理器缓存重载次数,提升了服务器的性能。例如你可以指定SQLServer只运行在一些CPU上,而不是所有可用的CPU上。

"affinity mask"选项的缺省值是0,这意味着SQLServer允许Windows调度算法设置线程的亲和力。换句话说,是操作系统而不是SQLServer决定哪个线程运行在哪个CPU上,什么时候将线程从一个CPU迁移到另一个CPU。在一个有4个或更少CPU的服务器上,缺省值时最好的设置。对于多于4个CPU的不是过度繁忙的服务器来说,对于最优性能来说缺省值也是最好的设置。

但是对于多于4个CPU有繁重负荷的服务器来说,由于一个或者更多的非SQLServer程序和SQLServer同时运行,你需要考虑将"affinity mask"选项的缺省值更改为一个更加合适的值。请注意如果服务器上只有SQLServer一个程序运行,使用"affinity mask"限制CPU的使用会伤害性能而不是提升性能。

例如,假定服务器运行了SQLServer,多个COM+对象和IIS,服务器有8个CPU并且是很忙的。通过将SQLServer运行的CPU数量从8个减少到4个,SQLServer线程现在仅仅运行在4个CPU上,而不是8个CPU上。这将减少SQLServer线程在CPU间迁移的次数,减少处理器缓存重载的频率,减少CPU使用率,从而潜在的提升一些性能。剩余的4个CPU将用来运行操作系统和其他非SQLServer程序,减少线程迁移,提升性能。

例如,一个8CPU的系统,使用SP_CONFIGURE命令设置SQLServer可以运行的CPU的值如下:
十进制值 允许SQLServer线程运行的处理器
1 0
3 0和1
7 0, 1和2
15 0, 1, 2和3
31 0, 1, 2, 3和4
63 0, 1, 2, 3, 4和5
127 0, 1, 2, 3, 4, 5和6

配置一个合适的affinity mask值是不容易的,你应该参考帮助文档以获得更多的信息。在你更改该选项的值后测试看看设置的值对性能是好还是坏。除了试错的方法,没有更好的方法为你的服务器设置一个合适的affinity mask值。

作为监控的一部分,如果你发现affinity mask使用的不是缺省值,请找出原因。如果没有好的答案,将该值修改为缺省值。

启用Awe

如果实在Win2000或2003的任何版本下运行SQLServer2000的标准版,或者是在Win2000或2003Server版下运行SQLServer2000的企业版,或者你服务器的内存少于4G,"awe enabled"选项将缺省为0,意思是AWE内存不被使用。

AWE(地址窗口扩展)API允许在Win2000或20003 Advandced Server下,或在Win2000或Win2003 DataCenter Server下运行的程序访问超过4G的内存。SQLServer2000企业版(不是标准版)是AWE可用的,这样能利用服务器超过4G的内存。如果操作系统是Win2000或20003 Advandced Server,SQLServer2000企业版能使用高达8G的内存。如果操作系统是Win2000或Win2003 DataCenter Server,SQLServer企业版能使用高达64G的内存。

缺省地,在Windows 2000 and 2003 (Advanced and Datacenter)下运行SQLServer2000企业版,如果物理内存超过4G,SQLServer也不能访问超过4G的内存。为了使操作系统和SQLServer2000企业版利用更多的内存,需要完成2个步骤。 正确的配置AWE内存支持依赖于你服务器有多少内存。本质上配置Win2000或Win2003(Advanced或DataCenter)必须在boot.ini文件的启动行添加下面的语句以打开AWE开关,然后重启服务器:
? 4GB RAM: /3GB (AWE支持不被使用)
? 8GB RAM: /3GB /PAE
? 16GB RAM: /3GB /PAE
? 16GB + RAM: /PAE
/3GB开关用来告诉系统允许SQLServer从Win2000和20003本身支持的4GB的内存中使用3GB。如果你不指定这个选项,SQLServer将仅仅值使用服务器第一个4GB内存中的2GB,这样就浪费了1GB的内存。

AWE内存技术仅仅用于超过4GB的内存,这就是为什么/3GB开关在你的服务器上被用来使用尽可能多的内存。如果你的服务器有16GB或者小于16GB的内存,那么使用/3GB开关是重要的。但是如果你的服务器有大于16GB的内存,那么你不必使用/3GB开关。原因是因为为了使用所有额外的AWE内存,1GB的额外内存需要服务器通过/3GB开关来提供。换句话说,如果你的服务器有大于16GB的内存的话,操作系统自身需要2GB的内存来管理AWE内存,如果你的服务器有16GB或者小于16GB的内存,那么操作系统置需要1GB的内存,允许SQLServer去使用另外1GB的内存。

一旦完成该步骤,接下来就是设置"awe enabled"的值为1,然后重启SQLServer服务。只有这样SQLServerf才能使用服务器里额外的内存。

使用"awe enabled"选项需要小心一点,就是在打开该选项后,SQLServer不再动态管理内存了。相反,它会使用所有可用的内存(除留给操作系统的128M的内存外)。如果你要禁止SQLServer使用所有的内存,你必须设置"max server memory"选项(将在后面做详细描述)来限制SQLServer使用内存。

作为监控过程的一部分,你要检查这个设置的值是多少,是否与服务器的硬件和软件匹配。如果不匹配,相应地修改这个值。

Cost Threshold for Parallelism

使用并行去执行SQLServer查询有一定的成本。这是因为并行比串行占用了额外的开销。但是如果并行的好处高于成本开销的话,那么使用并行还是值得的。

首要原则是,如果串行执行很快,就没有必要考虑用并行来完成,评估可能的并行所必须的额外时间也许会比串行长得多。

缺省地,如果查询优化器发现一个查询少于5秒就能执行完成,那么SQLServer不会考虑并行。可以使用SQLServer选项"cost threshold for parallelism"来更改5秒这个数字。该值可以在0到32767之间任意配置。所以如果你设置该值为10,这就意味着如果一个查询执行完成少于10秒的话,查询优化器不会考虑对该查询进行并行处理。

大多数情况下,你不用改变该值。但如果你发现你的SQLServer并行的运行了很多查询而CPU仍然很高的话,那么增加该值到一个大于5的值(你需要根据你的情形通过多次试错的方法来寻找一个理想的值),这样会减少使用并行的查询 的数量,也减少了CPU的使用率,这有助于提升你服务器的性能。

另一个考虑的选项是将5减少到一个更小的值,,尽管大多数情况下可能会影响性能而不是提升性能。一个更小的值在SQLServer的数据仓库运行很多复杂查询下可能是有用的,因为一个更小的值会使查询优化器使用更多的并行。

在你的服务器上使用一个修改的值前,你需要彻底地测试该值。

如果SQLServer仅用一个CPU(要么是因为服务器上只有一个CPU,要么因为"affinity mask"设定的值),并行是不会被考虑的。

如果你发现"cost threshold for parallelism"选项被使用,找出原因。如果你找不到答案,将其改回缺省值。

Cursor Threshold

如果你的SQLServer不使用游标或者很少使用,那么从不要更改该选项的的缺省值-1。

"cursor threshold"选项的值-1告诉SQLServer同步的执行所以的游标,如果游标的结果集不是很大,那么它是一个理想值。如果你的SQLServer有许多游标或者所以游标的结果集都很大,那么同步执行游标不是最有效的方法。

"cursor threshold"选项对于运行大的游标来说除缺省值外还有2个值可设置。一个值是0,它表示所有的游标都异步的执行,如果SQLServer有许多游标或者所以游标的结果集都很大,这会提高效率。

如果SQLServer有些游标的结果集小而另一些大,那么我们该怎么办呢?这种情况下,我们可以根据这些结果集的大小值来为SQLServer决定一个大小值。例如,考虑把结果集小于1000行的任何游标作为小结果集的游标,而大于1000行的作为大结果集的游标,这样,我们可以设置"cursor threshold"选项的值为1000。

当"cursor threshold"选项的值被设为1000,这意味着查询优化器对于那些结果集小于1000行的游标采用同步处理的方式。而结果集大于1000行的将采用异步方式处理。

大多数情况下,这个选项提供了最好的方式。唯一的问题就是需要决定"cursor threshold"值的大小,这需要进行测试。但是正如你所料,缺省值通常是最好的,如果你确定你的应用程序使用非常大的游标并且进行了测试以确定更改,那么更改该选项的值有助于性能的提升而不是影响性能。

作为监控的一部分,你也需要知道游标执行的频率,结果集的大小。这样就可以为你的服务器配置一个最好的值。当然你尽量在服务器上不要使用游标,这样就可以保留缺省值而不必担心游标了。

Fill Factor (%)

这个选项允许你创建索引时更改索引的缺省填充因子。缺省地,该值通常为0。0有点使人迷惑,因为它意味着叶索引页100%(不是0%)的被填充,但是中间索引页(非叶子页)有一些空间而不是被100%的填满。该选项的取值范围为0到100之间。

当创建索引时没有指定填充因子的值时系统会使用缺省的填充因子。如果指定了一个值,创建索引时会使用该值而不是缺省值。 大多数情况下,最好不要修改缺省值。如果你需要一个不同的值,在创建索引时指定即可。

作为监控的一部分,注意该值是不是不同于缺省值0。如果是,找出原因。如果你不能找到为什么要修改缺省值或者没有更好的原因,将其改回缺省值。 如果该值已经被更改,请记住任何索引在创建时都会使用这个更改后的缺省值。这样,你需要重新确定这些索引是否适合这个填充因子的值。

Index Create Memory (KB)

index create memory选项用来控制索引创建排序时所需的内存数量。默认值是0,这意味着SQLServer动态确定该内存数量。在几乎所有的情况下,SQLServer会确定内存的最佳值。

但在某些情况下,特别是对于非常大的表,可能导致SQLServer错误,因为大索引创建会很慢或根本不创建。如果你遇到这种情况,你需要设置一个Index Create Memory选项的值,尽管你不得不试错直到找到最佳值为止。该选项的合法范围在704到2147483647之间,它是SQLServer在创建索引时能提供的值,单位是KB。

记住如果你确实要改变该选项,这个内存值只分配给索引创建而对其他的操作不起作用。如果你的服务器有更多的内存,那么这不是问题。但如果你的服务器没有太多的内存,更改该选项的值可能对SQLServer的其他产生一些消极影响。你可以考虑仅在创建或重建大索引时更改该选项,其他时间改回缺省值。

和其他的选项一样,如果你监控发现该选项不同于缺省值,找出原因,如果找不到原因或者没有更好的原因,将其改回缺省值。

Lightweight Pooling

缺省地,SQLServer7.0和2000是以“线程模式”运行的。这就是说SQLServer使用UMS(用户模式调度)线程运行用户程序。SQLServer将为每个程序创建一个UMS线程,每一个线程在SQLServer忙时轮流处理许多用户程序。为了达到最佳效率,UMS试图平衡每个线程的用户程序数量,试图在服务器的所有CPU之间有效的均衡所有的用户程序。

SQLServer也有一个优化模式叫纤程模式。这种情况下,SQLServer对每一个处理器使用一个线程(象线程模式一样),但不同的是每个线程里运行多个纤程,当正在运行的一个线程对于服务器上其他运行的SQLServer线程没有优先级别的时候使用纤程。想想在某些环境下,纤程作为轻量级线程,对它的管理比标准的UMS线程用更少的开销。使用SQLServer的配置选项"lightweight pooling"来开启和关闭纤程模式,缺省是0,即纤程模式是关闭的。

所有这些意味着什么呢?象所有的事情一样,在一种模式下或者另一种模式下运行总是有其赞成者和反对者。一般说来,当下列所有条件成立时,纤程模式才是有利的:
? 服务器上有2个或更多的CPU(CPU越多,效果越大)
? 所有的CPU大多数时间都运行在接近最大值也就是90-100%之间
? 服务器上有许多context switching事件(性能监视器为系统对象:Context Switches/sec)。一般说来,每秒超过5000个context switches 事件就被认为过高了。
? 服务器正在产生使用很少或者根本没用的分布式查询或者扩展存储过程。
如果以上都满足,那么将"lightweight pooling"选项打开,也许会看到5%或更大的性能改善。

但是如果不满足任一条件,将"lightweight pooling"选项打开实际上可能降低性能。例如,如果你的服务器大量使用了分布式查询或者扩展存储过程,那么打开该选项会明确地引发问题,因为他们不能使用到纤程,即SQLServer不得不来回在纤程模式和所需的线程模式之间切换,从而影响性能。

和其他设置一样,如果你发现该设置不是缺省值,试图去找到原因。另外,检查上面四个条件是否存在,如果是,打开该选项,否则使用缺省值0。

Locks

每当SQLServer锁定一条记录时,锁会存储在内存中。缺省地,"locks"选项的值是0,即锁内存是动态管理的。SQLServer内部可以为锁保留2%到40%的可用内存。另外,如果SQLServer确定为锁分配额外的内存会引起操作系统级的页面调整,那将不会分配内存给锁,相反为了禁止页面调整会分配给操作系统。

大部分情况下,允许SQLServer动态管理锁,保留其缺省值。如果你配置锁内存(合法值在5000到2147483647 KB之间),那么SQLServer不能动态管理这部分内存,这可能引起SQLServer的其他区域的性能降低。

如果得到一个错误消息:超过最大的可用锁数量,那么你可以有以下办法:
? 检查查询看是否使用了过多的锁。如果是,性能可能会因为应用程序并发而受到影响。比改善坏查询更好的方法是为跟踪到的锁分配更多的内存。
? 减少服务器上的应用程序数量
? 为服务器添加更多的内存
? 对锁数量设置一个较高的值(基于试错)。这是一个最少令人满意的选项,和给锁分配内存以阻止SQLServer为了其他目的而占用内存一样。
最大努力地不要使用这个选项。如果你发现这个选项设置的不是缺省值,找出原因,如果你找不到原因或者原因太少,就改回缺省值。

Max Degree of Parallelism

该选项允许你将并行打开、关闭、或者为某些CPU打开,但不是为全部的CPU打开。并行指的是查询优化器使用多于1个CPU去执行查询的能力。缺省地,并行是打开的并且尽可能多的使用服务器的CPU(除非被affinity mask选项限制)。如果你的服务器只有1个CPU,该选项会被忽略。

这个选项的缺省值是0,这意味着并行是为所以可用CPU打开的。如果你改变该值为1,并行对所有CPU就关闭了。这个选项允许你设置并行能使用多少个CPU。例如,如果你的服务器有8个CPU,而你只想让并行运行在其中的4个CPU上,那么将该值设置为4。尽管这个选项是可用的,而想使用它来真正提高性能却是不确定的。

如果并行是打开的,正如多CPU的服务器缺省那样,那么查询优化器将评估每个查询使用并行的可能性,会带来一些开销。在许多OLTP服务器上,查询本身通常不会采用并行去运行。这包括标准的SELECT、INSERT、UPDATE、DELETE语句。因此,查询优化器在评估每一个查询是否值得用并行只是在浪费时间。如果你了解到你的查询可能从来不需要并行,你可以通过关闭该选项来获得性能的一点提升,因为不会为查询评估并行。

当然,如果查询本身能利用并行,你不需要关闭并行选项。例如,如果OLTP服务器上运行了许多相关联的子查询,或其他复杂的查询,那么你可能需要将并行开着。你需要测试这个选项看是否有所帮助。

大多数情况下,因为许多服务器既运行OLTP又运行OLAP查询,并行应该保存打开。作为你性能监控的一部分,如果你发现并行关闭或受限,找出原因。另外,确认服务器是不是基于OLTP的。如果是,关掉并行也许更合适,尽管你需要通过测试看关闭是否有助于性能的提升。但如果服务器既运行OLTP,又运行OLAP,或者大部分OLAP查询,那么为了全面提升性能最好将并行打开。

Max Server Memory (MB) & Min Server Memory (MB)

为了最佳的SQLServer性能,你需要确定你的服务器仅仅运行了SQLServer,而没用其他的应用程序。大多数情况下,"maximum server memory" 和 "minimum server memory" 选项设置为缺省值即可。这是因为缺省值为了最佳性能允许SQLServer动态分配内存。如果你修改了最大或最小内存设置,可能你会冒影响性能的风险。

另一方面,如果SQLServer不能运行在它自己的物理服务器上(其他程序和SQLServer运行在同一台物理服务器上),你需要考虑更改最小或最大内存值,尽管这通常是不需的。

让我们仔细研究一下这两个选项。

"maximum server memory"选项,当设置为缺省值2147483647(单位MB),意味着SQLServer动态管理内存,即SQLServer将尽可能使用可用内存(除留给操作系统一些必要的内存外)。

如果你想要SQLServer不使用服务器上所有的可用内存,你能手动设置最大内存。SQLServer能使用的指定的内存在4(你能输入的最小值)到你服务器上最大的物理内存(但不要分配服务器上所有的内存,因为操作系统也需要)。

仅当SQLServer必须和同一台服务器上的其他应用程序共享内存,或者你想人工保持SQLServer使用可用的内存,你才需要去改变缺省值。例如,如果你其他的应用程序比SQLServer性能重要,那么你可以限制SQLServer的性能。

如果你试图手动设置"maximum server memory" 选项的值,你可能会遇到两种潜在的性能瓶颈问题。第一,如果你分配了太多的内存给SQLServer,而对于其他的应用程序和操作系统没有足够的内存,那么操作系统别无选择地要做很多的页面调整,这将降低服务器的性能。而且,如果你使用了全文索引服务,你必须为它留出足够的内存。它的内存不是动态的分配,象剩余的SQLServer内存一样,要运行它必须有足够的适当的内存。

"min server memory"选项的缺省值0(单位MB),意味着SQLServer动态管理内存,即SQLServer将按照需要分配内存,最小值将随着SQLServer的需要而变化。

如果更改"min server memory"选项的值而不设置为缺省值0,这并不意味着SQLServer自动开始使用这个最小的内存设置,许多人是那样认为的,但是一旦由于需要超过了设置的最小的内存,那么将永远不再小于这个最小值。

例如,如果你设置了最小值为100MB,然后重启SQLServer,SQLServer不会立即使用100MB这个最小的内存。相反,SQLServer仅仅使用需要的内存。如果你从不需要100MB,那么将从不会使用100MB。但是如果SQLServer使用超过了100MB,而以后不再需要100MB,那么这100MB将成为SQLServer分配的最低内存。因此,没有理由将"min server memory"选项的值不设置为缺省值而改为其他值。

如果服务器上只有SQLServer,根本没有理由去使用"min server memory"选项。如果还运行了其他程序,改变该值可能会获得一些微小的好处,但决定设置为何值是很困难的,并且这个性能的提升基本上可以忽略。

如果你发现这些选项的值不是缺省值,找出原因。如果找不到原因,或者原因站不住脚,将它改回缺省值。

Max Text Repl Size

"max text repl size"选项可以设定在执行单个INSERT、UPDATE、WRITEEXT或者UPDATEEXT命令时可以增添到复制字段的 text 和 image 数据的大小(单位为字节)。如果你没用到复制或者复制没有用到text、image字段,那么该选项不用修改。

缺省值是65536,最小值是0,最大值是2147483647(单位为字节)。如果对text、image数据有很多的复制,仅当数据超过64K,你应该考虑增加该值。但与这些设置的最大值一样,你将不得不用各种值去实验看哪个值在你的特殊环境下效果最好。

作为监控的一部分,如果你不使用复制, 正确的值只有缺省值。如果缺省值被更改,你需要调查text、image数据是否被复制。如果没有,或者如果小于64KB,那么改回缺省值。

Max Worker Threads

SQLServer的配置选项"max worker threads"被用来决定操作系统上的sqlservr.exe进程允许有多少个工作线程可用。缺省值是255个工作线程。SQLServer自身使用一些线程,我们不讨论这些线程。这里将焦点放在那些由用户创建线程上。

如果有多于255个用户连接,那么SQLServer将使用线程池,即多于一个用户连接使用一个工作线程。尽管线程池减少了SQLServer使用的系统资源,它也能在访问SQLServer的用户连接之间增加资源争夺,从而影响性能。

为了找出你的SQLServer运行了多少个工作线程,使用企业管理器检查目前你服务器的连接数量。对于每一个SQLServer连接,都有一个工作线程被创建,最高到"max worker threads"选项设置工作线程总数。例如,如果有100个连接,那么有100个工作线程将被创建。但如果有500个连接,但只有255个工作线程可用,那么只有255个工作线程被使用,其余打开的连接共享这些有限的工作线程。

如果你的服务器有足够的内存,为了得到最好的性能,你要设置"max worker threads" 选项的值为你服务器曾经达到的最大的用户连接数再加5,但这个常规的建议存在一些局限,正如一会儿我们看到的。

前面已经说过,"max worker threads"的缺省值是255。如果你的服务器从未超过255个连接,那么不必改变这个缺省值。这是因为工作线程仅在需要的时候创建。如果仅有50个连接到服务器,那么将仅只有50个工作线程,而不是255这个缺省值。

如果你的服务器通常超过255个连接,而"max worker threads"的设置仍然是缺省值255,那么SQLServer将使用线程池。现在进入了两难的局面。如果你增加"max worker threads"的值一个线程一个连接,SQLServer将占据额外的资源(更多的内存)。如果你的服务器有很多未被SQLServer或其他程序使用的内存,那么增加"max worker threads"的值将提升SQLServer的性能。

但是如果没有另外可用的内存,那么添加更多的工作线程会影响SQLServer的性能。在这情况下,允许SQLServer使用线程池来提供更好的性能。这是因为线程池使用更少的资源(比起不使用线程池来)。但是,消极的一面,线程池在连接之间会产生资源争夺的问题。例如,共享一个线程的两个连接同时执行一些任务的时候会产生冲突(因为一个线程同时只能为一个连接服务)。

那么该怎么办呢?简而言之,如果你的服务器通常少于255个连接,保留缺省值设置。如果你的服务器超过255个连接,且有更多的内存,那么考虑增加"max worker threads"设置的连接数再加5。但如果没有太多的内存,保留缺省值。对于有成千上万连接的SQLServer来说,你需要通过试验找到在额外的工作线程使用额外的资源和争夺相同工作线程的连接之间的分界线。

也许正如你所期望的,在使用这个选项之前,你要在改变该设置的前后测试服务器的性能,看看SQLServer的性能是提升还是下降了,从而确定一个合适的值。

作为监控的一部分,按照上面给出的建议来设置该选项的值。

Min Memory Per Query

当一个查询运行时,为了运行得更快更有效率,SQLServer尽量分配合适的内存给查询。缺省地,"minimum memory per query"选项分配的是1024KB,这是每个查询运行的最小内存。"minimum memory per query"选项可以在0到2147483647 KB之间设置。

如果查询需要更多的内存运行才有效率,且有可用内存,那么SQLServer自动的分配更多的内存给查询。因此,通常不建议修改该选项的缺省值。

在某些情况下,如果SQLServer比有效率的运行有更多的内存,那么增加该选项的值到一个更高的值(如2048KB或更高)可能提升某些查询的性能。一旦服务器有更多可用的内存(本质上,这些内存没有被SQLServer使用),那么提高该选项的值能全面提升SQLServer的性能。但如果没有,增加该选项的值可能降低性能而不是提升。

Nested Triggers

这个配置选项的确影响性能,但不在常规的方法里。缺省地,"nested triggers"选项的缺省值为1。意即可以运行嵌套触发器(触发器最多能够嵌套32层)。如果将其设置为0,那么将不运行嵌套触发器。显然,通过不允许嵌套触发器,能够全面提升性能,但要以应用程序的灵活性作为代价。

请保留该选项的缺省值,除非你要防止开发人员使用嵌套触发器。一些依靠嵌套触发器的第三方程序如果关闭嵌套触发器也会运行失败。

Network Packet Size (B)

"Network packet size"决定SQLServer通过网络与客户端会话时信息包的大小。缺省值是4096字节,该值的最小值最大可设为512字节,最大值依赖于使用的网络协议所支持的值。

理论上,改变该值以或多或少适应数据包的大小可以提升性能。例如,如果数据很小,平均小于512字节,更改缺省的4096字节到512字节可以提升性能。或者,如果你在做大量数据的移动,如大批量的导入或在处理大量的TEXT、IMAGE数据,那么增加该值以大于缺省值,这样会发送较少的包,从而提高性能。

理论上,这听起来很好。实际上,不管哪个,你看到的性能提升很少。这是因为没有考虑平均的数据大小。某些情况下数据很小,另一些情况数据很大。因此改变这个选项的缺省值通常没有太多的帮助。

作为监控的一部分,小心检查每一个不是缺省值的设置。如果找不到答案,改回缺省值。

Open Objects

"Open objects"指的是SQLServer能同时打开的对象(包括表、视图、默认值、触发器和存储过程)的数量。该选项的缺省值是0,意味着SQLServer为了获得最好的性能动态的增加或减少该值。

很少情况下,可能会得到一个信息说打开的对象超过可用的数量,通常这种情况是服务器内存全被使用了。解决它的最好方法是增加服务器的内存或者减少服务器的负载,如减少服务器维护的数据库的数量。

如果上面两个选项都不满足实际,可以手动配置给该选项一个适当的最大值。这个问题是双方面的。首先,决定适当的值需要太多的试验。其次,给打开对象分配的任何内存将被其他的SQLServer需求使用,潜在的降低服务器的整体性能。当然,当你改变该选项的值你的应用程序也会运行,不过会变慢。避免改变该选项的值。

当你监控性能时,如果发现该值不是0, 要么是有人犯错误需要纠正,服务器的硬件太小,为它添加更多的内存,要么是服务器工作需要移到另一个不是很忙的服务器上。

Priority Boost

缺省地,SQLServer进程和服务器上其他应用程序有相同的优先级别。也就是说,没有个别的应用程序进程在获得CPU时钟时有比其他进程更高的优先权。

"priority boost"配置选项允许改变。缺省值是0,即SQLServer进程和其他的应用程序进程有相同的优先权。如果改为1,那么SQLServer有比其他应用程序进程更高的优先权。本质上,这意味着SQLServer比同一服务器上的其他应用程序进程有第一优先权使用CPU时钟。但是这真能提升SQLServer的性能吗?

让我们看看一对情形。首先,假定服务器不只运行SQLServer,也有其他的应用程序(为了最好的性能不推荐这样使用,但真实世界有可能存在这种情形),且有很多的CPU可用。如果是这种情形,给SQLServer一个更高的优先权会怎样呢?不怎么样。如果有很多可用的CPU,提高优先权并不意味着什么,和其他程序相比,SQLServer也许获得一些毫秒级的时间,但我怀疑你能注意到这个区别。

现在让我们看看上面这个熟悉的场景,但是假定CPU事实上都耗尽了。如果是这种情况,给SQLServer一个更高的优先权当然会运行得更快,但是只有以其他应用程序运行得慢为代价。如果这是你需要的,那么没问题。但更好的解决方法是提升服务器上CPU的能力或减少服务器的负载。

但如果SQLServer运行在一个没有其他应用程序的专用服务器上且有很多过剩的CPU可用呢?这种情况下,提升优先权没有用,因为没有CPU竞争(除了部分操作系统进程外),而且有很多CPU还可用。

最后一种情形,假如SQLServer运行在专用服务器上,且CPU没有空闲,给更高的优先权是一个零和游戏,这样做潜在的给一部分操作系统以消极的影响。而SQLServer获得的性能却很少。

正如你所见,这个选项不值得修改。事实上,微软有文档说明使用这个选项的几个问题,试图使用这个选项甚至很少令人满意。

如果在你的监控列表里发现该选项打开,找出目的。如果打开它目前没有任何问题,你可能会没有问题的打开它,但是我建议改回缺省值。

Query Governor Cost Limit

"query governor cost limit"选项设置查询所能运行的最高时间限制,这是我认可的少数几个SQLServer配置选项之一。例如,假定你服务器的一些用户喜欢运行长时间的查询,这真正会降低你服务器的性能。通过设置该选项,你能禁止运行任何超过300秒(或者任何你确定的数)的查询。缺省值是0,即一个查询运行多长时间都没有限制。

你为这个选项设置的值是一个近似值,并且基于查询优化器估计出的查询运行的时间。如果估计值比你提供的值要多得多,查询根本不会运行,反而产生一个错误。这能节约大量的有用的服务器资源。

另一方面,如果用户不得不为了完成他们的工作而由于你他们不能运行查询,他们将真正感到不快。也许你考虑该做的是帮那些用户写更有效率的查询。这样,大家皆大欢喜。

不象我的其他很多建议,如果你的监控列表里该值大于0,很好。只要用户不抱怨,这就是一个好的处理。事实上,如果设置为0,这儿考虑增加一个值,看看发生了什么。只是不要加得太小。可以考虑一开始加600秒,看看发生了什么。如果没问题,然后试试500秒,依此类推,直到你发现用户开始抱怨位置,然后改回前一个值。

Query Wait (s)

如果SQLServer很忙且在不断使用更多的内存资源,它将大量占用内存的查询(如那些涉及排序和哈希操作的查询)排队等待,直到有足够的内存运行它们。有些情况下,没有足够的内存运行它们,最终会超时,产生一个错误消息。缺省地,一个查询运行的时间如果超过查询优化器估计它运行要花费的时间的25倍后,该查询将超时。

这个问题的最好的解决方法是给服务器添加更多的内存,或者减少它的负载。如果你不能这么做的话,一个可选项就是使用"query wait"配置选项,尽管它本身有很多问题。缺省值是-1,等待的时间如上所述,然后引起超时。如果你要时间很大以便查询不超时,可以设置"query wait"一个足够大的值。正如你也许猜到的那样,你将不得不通过试错决定该值。

使用这个选项的问题在于有这样一个查询的事务可能会保持锁,这会引起死锁或者其他一些锁争夺的问题,最后出现一个比查询超时更大的问题。因此该选项不建议修改。

如果在你的监控列表里发现该选项没有设置为缺省值,找出原因。如果没有好的原因,请改回缺省值。但是如果有人彻底考虑过它,且你也没有发现锁问题,那么考虑保持现状。

Recovery Interval (min)

如果你有一个有很多INSERT、UPDATE、DELETE的活动频繁的OLTP服务器应用程序,"recovery interval"的缺省值0(意味着SQLServer自动决定适当的恢复时长)也许不合适。如果你正用性能监视器监视你服务器的性能,注意有一个规则的100%的磁盘写活动的周期(发生在检查点运行期间),你要设置该选项一个更高的值如5或10。它表示SQLServer重启后恢复数据库所需的最大分钟数。缺省值是0,实际上,这表示每个数据库的恢复时间不超过 1 分钟。

使用该选项的另一个潜在的原因是如果服务器是OLAP或数据仓库专用服务器的情形。在这些实例里,有很多只读数据库通常从一个短小的恢复时长里得不到好处。

如果你的服务器不匹配上面的任一建议,那么保留缺省值通常是最好的选择。

通过延长检查点时间,可以减少SQLServer执行检查的次数,如果有效,减少SQLServer的一些开销。在性能和为SQL花费的时间之间找到一个折中方案需要多次试验。为了减少下次SQLServer重启需要的恢复时间你需要配置一个尽可能小的值。这是因为每次SQLServer服务启动时,它将经历自动恢复过程,该选项的值设得越大,恢复过程花费得时间就越长。你不得不决定在性能和恢复时长之间找到一个折中的方案以便最适合你的需求。

作为监控的一部分,你要估计该选项目前的设置和它潜在的使用。对于繁忙的OLTP服务器来说,在你决定增加该选项的值看看是否有帮助之前你要做大量的调查。测试是重要的。但如果你的服务器是OLAP或数据仓库专用服务器,增加该选项的值是一个很容易做出的决定。

Scan for Startup Procs

如果得到正确的配置,SQLServer服务启动时有能力去寻找自动运行的存储过程。如果你想在启动时做一些特定的操作这是有利的,如载入一些特定的存储过程到缓存里以便当用户开始访问服务器时它已经是准备好的。

缺省地,"scan for startup procs"选项设置为0,意味着启动时不扫描存储过程。如果你没有任何在启动时要启动的存储过程,那么这是一个显而易见的设置。不必花费资源去寻找那些不存在的存储过程。

但如果你有一个或多个存储过程想在服务启动时执行,那么该选项需要设置为1,表示启动时扫描。

如果你在你的监控列表里发现该选项的值为1,检查看是否有任何服务器启动时要执行的存储过程 。如果没有,将该选项的值改回缺省值。

Set Working Set Size

当你要更改SQLServer启动时使用的最大和最小的内存时就要用"set working set size"选项。这个选项也帮助你禁止任何页面交换。

该选项的缺省值为0,即不使用该选项。要打开这个选项,必须将它设置为1,并且,最小的内存和最大的内存要设置为相同的值。该值用来保留等于服务器内存设置的物理内存空间。

和许多选项一样,这个选项通常也不必使用。仅在服务器是SQLServer专用服务器且工作量很大还有很多可用的内存时才考虑。即使那样,任何性能的提升也是最小的,你还要冒潜在的没有留给操作系统足够内存的风险。测试是该选项成功使用的关键。

如果该选项设置为不是缺省值的另外的值,检查最小的内存和最大的内存是否相同,否则这个选项将不会正确的工作。如果存在上面提到的条件并且经过彻底的测试,那么考虑保留设置。否则,改回缺省值(不要忘记改回所有相关的3个设置)。

User Connections

缺省地,SQLServer仅分配需要的用户连接数。这允许那些需要连接的用户连接,同时最小化内存的使用。当"user connections"选项设置为缺省值0时,用户连接数动态设置。事实上在所有的环境下,这个设置都时理想的设置。

如果你改变了该选项的值而不设置为缺省值,你是在告诉SQLServer将分配一个你指定的连接数给它,不多不少。它也将为每个连接分配内存,不论这个连接是否使用。由于这些问题,且SQLServer能动态有效的处理这些任务,没有理由改变该选项的缺省值而设置为其他值。

如果你的监控里显示该值不为0,将其改回0。甚至都不要问为什么。

SQLServer数据库设置性能列表

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址

性能监控列表
数据库配置选项 缺省值 当前值
auto_close off
auto_create_statistics on
auto_update_statistics on
auto_shrink off
read_only off
torn_page_detection on in 2000
off in 7.0
compatibility level 80 for 2000
70 for 7.0
database auto grow on
transaction log auto grow on

输入你的结果到上表

每一个数据库都需要监控

作为性能监控的一部分,你需要检查你服务器上的每一个数据库和一些基本的数据库设置。和这套监控列表的其他监控相比,你会发现该监控是最容易的。为了方便,你可以将你要监控的每个数据库做一个上表的副本。

作为数据库设置监控的一部分,我们来看看数据库选项和数据库配置设置之间的不同。在以前的性能监控列表中,我们仅仅着眼于那些直接和性能相关的数据库设置,而忽略了其余部分。

数据库选项和数据库配置设置都能使用企业管理器查看和修改(我偏好它,因为简单),或者用ALTER DATABASE命令修改。另外,仅对于数据库选项而言,还可以使用sp_dboption系统存储过程去查看和修改它们,但微软正试图逐步淘汰这个命令,到SQLServer2000为止,以后可能不再支持。

数据库设置性能监控列表的第一部分是数据库选项,第二部分着眼于数据库配置设置。

查看数据库选项

在这一部分,我们将仅仅察看以某种方式影响性能的众多数据库选项中的6个。察看目前设置的最好方法是用企业管理器,步骤如下(假定用的是sqlserver2000):
• 在企业管理器里,展开所有的数据库。
? 右击你要察看的数据库,选择属性。
? 在属性对话框里选择选项标签。
从这里你可以看到所有相关的数据库选项。记住不是每个数据库选项都能在这儿看到,但是我们感兴趣的所有的选项都列在这儿了。让我们看看与性能相关的那些选项,它们是怎样影响SQLServer的性能的。

Auto_Close

这个数据库选项是为SQLServer7.0和2000的桌面版本设计的,而不是为服务版本。因此,它将不会被打开(缺省也不是打开的)。该选项所要做的就是在最后一个数据库用户从数据库断开连接时关闭数据库。当一个连接在数据库关闭后要求访问它时,数据库不得不重新打开,这会花费时间。

这样有个问题就是:如果数据库被频繁的访问(这是经常的情况),那么数据库会不断的关闭重新打开,这样应用程序或用户在连接时会很大的影响SQLServer的性能。

作为监控的一部分,如果你发现这个选项被打开,而你又使用的不是桌面版,那么你需要找出原因。如果你找不到原因,或者原因很少,那么关闭该选项。

Auto_Create_Statistics

当auto_create_statistics打开时(缺省也是打开的),查询的Where子句用到的所有列上会自动创建统计。这发生在查询被查询优化器第一次优化时,假定这列还没有创建统计。所有的列统计能极大的帮助查询优化器,以便它能为查询创建一个优化的执行计划。

如果该选项关闭,那么丢失的列统计不会自动创建,这就意味着当查询优化器不能为查询产生优化的执行计划时,查询的性能将受到影响。如果你原意,你仍然可以手工创建列统计,即使该选项被关闭。

使用该选项真正没有负面的影响。恰好第一次列统计被创建,这将在查询第一次运行前花很短的时间,从而引起查询潜在的花费更长一点的时间运行。但一旦列统计已经创建,每次运行同样的查询时,都将比第一次不存在统计时更有效率。

作为监控的一部分,如果你发现这个选项被关闭,你需要找出原因。如果你不能找到原因,或者原因很少,那么打开这个选项。

Auto_Update_Statistics

为了使查询优化器做出更快的查询优化决策,列和索引统计需要更新。确保它的最好方法是打开数据库选项auto_update_statistics(缺省也是打开的)。这能帮助确保优化器统计是有效的,帮助确保查询运行时是被完全优化的。

但这个选项不是万能的。当SQLServer数据库在繁重的负载之下,有时auto_update_statistics可能在不恰当的时候更新一个大表的统计,如一天最忙的时候。

如果你发现auto_update_statistics在不恰当的时候运行了,你也许要关闭它,然后在数据库不繁忙的时候手工更新统计(使用UPDATE STATISTICS)。

但是还要考虑的一点是如果关闭auto_update_statistics选项将发生的事情。关闭该选项也许会在一天中不恰当的时候不运行统计更新来减少你服务器的压力,它也能引起你的一些查询得不到正确的优化,从而在繁忙的时候引起服务器的另一些压力。

象其他优化问题一样,你可能要通过试验来看开关这个选项是否对你的环境更有效。但是首要的原则是,如果你的服务器不是最繁忙的,那么打开该选项也许是最好的选择。

Auto_Shrink

一些数据库需要周期性的收缩以便删除数据库旧的数据来释放磁盘空间。但不要企图用auto_shrink数据库选项,这可能浪费不必要的数据库资源。

auto_shrink选项缺省是关闭的,这意味着只有一个方法去释放数据库里的空的空间,那就是手动去做。如果打开该选项,SQLServer将每隔30分钟检查看看是否需要收缩数据库。这样不仅使使用的资源上升(这些资源本来可以在别处得到更好的利用),也可能当auto_shrink进程在最繁忙的时间启动并工作时引起不可预料的瓶颈。

如果你需要周期性的收缩数据库,使用DBCC SHRINKDATABASE或者DBCC SHRINKFILE命令手工执行这一步或者使用SQLServer代理或创建一个数据库维护计划在不忙的时候进行周期性的调度。

作为监控的一部分,如果你发现该选项是打开的,你需要找出原因。如果找不到或者原因很少,那么关闭该选项。

Read_Only

如果一个数据库仅为了只读目的,如为了报表,那么考虑设置read_only选项(缺省是关闭的)。这将除去那些资源利用多的锁,潜在的轮流提升它上面运行的查询的性能。如果你很少更改数据库,那么关闭该选项,当要更改的时候再打开。

Torn_Page_Detection

由于SQLServer的数据页面(8K)和NT Server或者Windows Server(512字节)是不同的尺寸,可能在电源故障或者磁盘驱动、物理磁盘问题时数据库会变得不完整。

下面是原因。每当操作系统写一个SQLServer的8K数据页到磁盘时,都必须把数据分成多个512字节的页面。在第一个512字节的数据写完后,SQLServer假定整个8K的页面已被成功写入磁盘。所以如果在8K的SQLServer页面分成的所有512字节的页面写入磁盘之前出现了电源故障,那么SQLServer不知道发生了什么事情。这被称为残缺页。

正如你所想象的那样,这损坏了数据页面,也损坏了整个数据库。没有办法将数据库损坏的原因归结到残缺页,除非通过一个已知完好的备份备份恢复。防止这个问题的最好的方法之一就是确保服务器有一个备用电池。但这不能防止所有的问题,因为一个有缺陷的磁盘驱动也能引起类似问题(我曾经见过)。

如果你担心SQLServer数据库出现残缺页问题,你能让SQLServer告诉你他们是否发生(尽管这不能防止问题发生,也不能事后修正它们)。有一个数据库选项叫做"torn page detection"能在数据库级打开或者关闭。如果该选项打开,且如果发现了残缺页,那么数据库会被标记为不完整,且你基本上没有什么选择余地只能用你最近的备份恢复你的数据库。

在SQLServer7.0里,这个选项缺省是关闭的,且你必须为你要在上面用这个选项的每一个数据库上打开。在SQLServer2000里,这个选项默认是为所有数据库打开的。

那么最大的问题是:为什么不只打开它而变得安全呢?这个问题的原因在于打开该选项会影响SQLServer的性能。 你记住的不要太多,仅仅记住一点,如果你的SQLServer有很高性能问题,那么关闭该选项可能有一个明显的区别。作为一个DBA,你必须在是否使用该选项上做出决定,为你的特别的环境做出决定。

查看数据库配置设置

这一节我们将只查看三个数据库配置设置,检查它们是怎样影响性能的。查看它们最好的方法是用企业管理器,参考下面的步骤(这些步骤适合于SQLServer2000):
? 在企业管理器里,显示你的服务器里所有的数据库
? 右击你要查看的数据库,选择属性
? 从属性对话框里,选择选项标签查看兼容级别,选择数据文件标签查看数据库自动增长设置,选择事务日志标签查看事务日志自动增长设置。
让我们看看三个相关数据库配置设置的每一个。

Compatibility Level

SQLServer7.0和2000有一个数据库兼容模式,允许为以前版本的SQLServer写的应用程序在7.0或者2000下允许。在你想要最大化你数据库的性能里,你不要在兼容模式下运行你的数据库(不是所有新的性能相关的特征都被支持)。

相反,你的数据库应该运行在本来的SQLServer7.0或者2000模式下(依赖于你目前运行的版本)。当然,这会要求你修改你的应用程序使其适应SQLServer7.0或2000,但大多数情况下,这些额外的又是必须的升级应用程序的工作将对提升性能有更多的回报。

SQLServer7.0的兼容级别是70,2000的兼容级别是80。

Database and Transaction Log Auto Grow

我们将一起讨论数据库自动增长和事务日志自动增长,因为它们关联得很近。

如果你设置SQLServer7.0或2000的数据库和事务日志自动增长(缺省也是),记住每当这个选项起作用时,它将花费一些额外的CPU和I/O。理论上,我们应尽量减少自动增长发生的频率以便减少不必要的性能负担。

一个有用的方法时尽可能精确的度量数据库最终的大小。当然,事实上要得到正确的目的几乎是不可能的。但如果估计得越精确(有时得到这个好的估计要花费一些时间),sqlserver不得不自动增长数据库和事务日志就会越少,有助于提升你应用程序的性能。

下面一些对事务日志的独特建议是重要的。这是因为很多时候SQLServer不得不增长事务日志的大小,SQLServer不得不创建和维护更多的事务日志文件,当需要恢复事务日志时会增加恢复时间。一个被SQLServer使用的事务文件本质上被分成多个物理事务日志文件管理。

缺省的自动增长比例为数据库和事务日志的10%。这个自动增长数字对你的数据库和事务日志也许有好有坏。如果你发现数据库和日志经常自动增长(比如一天一次或者一周几次),那么改变这个增长百分比到一个较大的数字,如20%或30%。每次数据库或日志增长时,SQLServer都将有一个小的性能下降。通过增加每次数据库增长的数量,让增长不是很频繁的发生。

如果你的数据库很大,10G或者更大,你也许要用一个固定的增长量来代替百分比增长量。这是因为百分比增长量在一个大数据库上会变得很大。例如在一个10G的数据库上一个10%增长率意味着当数据库增长时,要增长1G。这也许是或不是你所要的。如果这超过了你的需求,那么选择每次增长一个固定增长量如100M,也许更合适。

作为监控的一部分,你需要小心估计你的数据库看上面的建议是否适合它们,然后做出正确的选择。

索引性能监控列表
索引列表 你的答案
你最近是否运行过索引调优向导?
每个数据库里的每个表是否有聚集索引?
每个表的任一列是否被多次索引?
查询里是否有没有被使用的索引?
索引是否太宽?
连接的表的连接列上是否有适当的索引?
索引是否足够唯一到有用?
覆盖索引是否带来了好处?
索引重建的频率是多少?
索引的填充因子是多少?
输入你的结果到上表。

审核索引的使用情况不是一件容易的任务,但对于你服务器的性能来说是紧迫的

在审核SQLServer数据库里索引的使用情况的时候,有时我很受打击。例如,怎样去审核超过1500个表的数据库的索引?审核单个索引相对简单些,审核多个数据库里的成千上万个索引就不是一件容易的任务了。不管这项任务是否容易,对于优化SQLServer数据库的性能来说却是重要的。

在着手处理大量索引的审核时有两个不同的方法。一个是分成更小的更容易管理的单元,首先着眼于那些最可能影响SQLServer性能的索引。例如,你可以在你服务器最忙的数据库上启动审核,如果它有很多表,首先从最多数据的那些表开始,然后逐步到那些少一点的表。这样,你将在那些最可能有很大实际影响服务器性能的地方看到最初的成就。

另一个方法,也是我通常使用的方法(因为我有点懒),就是使用排除法。我的意思是如果看不到数据库的任何性能问题,就不必要评估数据库的每一个索引。但如果数据库显示正好存在性能问题,那么对那些不是最优的索引来说是一个好的调优机会,特别注意它们,尤其在数据库任务紧急的时候。如果有大量的索引要审核,那么先从最大的入手,因为它们最可能引起性能问题。例如,在有1500个表的数据库里,我仅仅小心的审核大约一打的表(都是很大的表),我认为它们应该受到最多的关注。

不管怎样,当你决定审核你所管理的数据库的索引的时候,你需要拿出合理的计划并系统地实现。

正如你已经看到的,我上面提供的审核列表不是很长。这是故意的。记住,这一系列关于性能监控的文章的目的是为了分辨容易和显而易见的性能问题,不是找出全部。上面列出来的将使你走很长的路去分辨和纠正容易的与索引相关的性能问题。一旦你掌握了它们,就可以更上一层楼了。例如,本网站上有很多索引相关的提示,大部分都很高级,比如下面的主题:
? 普通索引
? 聚集索引
? 复合索引
? 覆盖索引
? 非聚集索引
? 重建索引
? 索引调优向导
如果你还没有做过的话,你需要复习这些提示的网页。

你最近运行过索引调优向导吗?

微软在SQLServer7.0和2000里给我们最好的工具就是之一就是索引调优向导。它不是一个完美的工具,但它确实能帮助你分辨存在的索引是否正被使用,同时提供能加快查询的新索引。如果你正使用SQLServer2000,它也能推荐索引视图的使用。它使用目前你正在数据库里运行的查询,所以它的建议是基于你数据库是真正怎么使用的。它用来分析所需的查询来源于你用SQLServer事件探查器创建的跟踪。

当在一个新的SQLServer上进行性能审核时我做的第一件事就是在捕捉到的服务器活动的跟踪上运行索引调优向导。大多数情况下,它能帮助我快速的分辨出任何一个不被使用的可以被删掉的索引,分辨出为了提升数据库性能需要新建的索引。

这里有一些对于在使用索引调优向导审核SQLServer数据库索引时的提示:
? 当你在使用事件探查器捕捉数据时(索引调优向导用来分析性能),选择一天中数据库正常负荷的具有代表性的时段。我通常喜欢选择在上午或者下午3点,然后运行事件探查器跟踪至少一个小时以上。
? 一旦事件探查器跟踪完,索引调优向导可以随时运行。但是,一个好的想法是在数据库一段时间不忙的最适宜的时候运行,这是因为使用索引调优向导进行性能分析时会影响服务器的一些性能,既然不必要,对服务器性能产生负面影响就毫无意义。也要避免在产品服务器上运行分析(向导仍不得不连接到产品服务器),当执行分析的时候在另一台服务器上运行向导可以减少产品服务器的负载。
? 尽管要花费更多的时间去完成分析,你需要在索引调优向导的几个选项的设置期间列一个清单来帮助进行彻底的分析。这些包括:不要选择"Keep all existing indexes"(保留所有现有索引),因为你要分辨哪些索引没有用;指定你要进行"Thorough"(彻底的)分析,而不是"Fast"(快速)或者"Medium"(适中);不要选择"Limit the number of workload queries to sample"(将要抽样的工作负荷查询的数目限制为)选项,保留"maximize columns per index"(每个索引的最大列数)设置的最大设置为16;选择所有被用来调优的表。通过选择这些选项,索引调优向导将进行彻底的工作,尽管要花费几个小时才能完成,这依赖于跟踪文件的大小和你执行分析的硬件的速度。注:这些只针对SQLServer2000,SQLServer7.0稍微有些不同。
? 一旦分析完成,向导也许没有任何建议,也许建议删除一个或更多的索引,或者建议添加一个或更多的索引,或者建议既添加也删除。你需要在采纳建议之前小心评估它们。例如,向导也许建议删除一个特殊的索引,但你知道该索引是真正需要的。那么当你知道这不是一个好想法可为什么向导建议删除呢?这是因为向导没有分析在跟踪文件(仅仅是一个抽样而已)里发现的每一个查询,加之你的抽样跟踪数据可能没有包括需要那个索引的查询。这种情况下,向导也许建议删除该索引,即使这不是一个好的建议。一旦你检查到一个索引是不需要的,你应该删除它。
? 如果向导建议添加新的索引,那么你要评估它们,也要和目前表上存在的索引比较看看它们是否有意义,会不会引起潜在的新的问题。例如,一个建议的索引或许能帮助一部分查询,但它也可能降低每小时成千上万次的INSERT操作。向导不知道这些,你必须决定哪个更重要,一些查询运行快了点而INSERT去慢了,反之亦然。
? 最后,即使索引调优向导没有任何新索引的建议,这也不意味着新索引是不需要的,仅仅根据跟踪数据来分析可能不会有任何建议。为了更好的帮助分辨出需要的索引。你要考虑好几天运行多个跟踪以便得到更多的抽样数据。即使那样,索引调优向导也不能找出全部需要的索引,但它将找出所有显而易见需要的索引。
一旦你完成分析并根据建议做出了更改,我建议你再次跟踪分析以便看看你的更改是否有效果。谨记索引调优向导分析不是一蹴而就的事情。随着时间的推移数据库的数据发生了潜在的变化,随着一起变化的还有查询的类型。所以,作为一个要点:定期的对服务器进行跟踪和分析以保持定期的优化。

每个数据库的每个表都有聚集索引吗?

首要的原则是每个表都应该有聚集索引。聚集索引通常但不总是应该建在单调递增的一列上如自增列,或者其他的值是递增并唯一的列上。大多数情况下,主键是作为聚集索引理想的列。

如果你曾经调优过SQLServer6.5的性能,你也许听说在单调递增列上创建聚集索引不是一个好的方法,因为它可能由于磁盘的"hotspot"(热区)引起性能问题。那个建议在SQLServer6.5中是正确的。

在SQLServer7.0和2000中,"hotspots"通常不是问题了。只有在每秒超过1000个的事务的情况下,"hotspot"才对性能有负面的影响。事实上,"hotspot"在这些环境下是有用的,因为它消除了页拆分。

下面是原因。如果你正在向一个主键上建聚集索引的表里插入新的行,主键是单调递增的,这意味着每个INSERT将在磁盘上逐个的物理顺序出现,因此,页拆分不会发生,这本身就节省了资源。这是因为SQLServer有能力决定数据是否被插入到有单调递增序列的表里,如果是,就不会执行页拆分。

如果你正插入很多行到一个堆表(没有聚集索引的表)中,数据不会按任何特定的顺序插入到数据页,不管数据单调递增与否。这样当从磁盘上访问数据时,SQLServer会花费更多的读操作。另一方面,如果给表添加聚集索引,数据被顺序的插入到数据页上,通常在读取数据时花费更少的磁盘I/O。

如果数据被插入到一个或多或少有随机顺序的聚集索引里,数据通常是随机的插入到数据页里,就象堆表一样,会发生页拆分。

那么说回来,为了全面的提升性能,最好的建议就是在一个单调递增列(假定有一列是符合条件的)上添加聚集索引。如果表上有很多INSET、UPDATE和DELETE操作更是应该这样。但如果表的更改很少,大部分是SELECT语句,那么这个建议就不是很有用,为聚集索引考虑其他的选择。

作为索引监控的一部分,检查看看数据库里每个表是否都有索引。如果根本没有索引,认真的考虑给添加一个聚集索引,参考上面的建议。事实上给表添加一个聚集索引不会比没有聚集索引时引起性能下降。

每个表的任一列是否被多次索引?

听上去这个建议是显而易见的,但它比你认为的要普遍得多,特别是多个DBA每人管理一段时间的数据库。SQLServer不关心你是否这样做,只要索引的名称不同它就认可了。所以当检查表目前的索引时,看看是否有列在不必要的重复索引中。删除它们不仅能节约磁盘空间,也能加快对表数据的访问和修改。

重复索引的一个通常例子就是忘记了列上有主键,或者列是唯一的,这样列上会自动创建索引,可是又在上面以不同的索引名称创建了索引。

查询里是否有没有被使用的索引?

这里有另外一个显而易见的建议,但也是一个普遍的问题,特别是在数据库正式启用以前DBA或开发人员猜测的为数据库创建的最初的那些索引。仅仅看看表的索引不会告诉你这些索引是否有用,所以分辨没用的索引通常是不容易的。

分辨没用的索引的最好途径是使用索引调优向导,前面讨论过。

不必要的索引,象重复索引,既浪费磁盘空间又对数据的访问修改的性能没有多大的好处。

索引是否太宽?

索引越宽,明显地就变得越大,访问或修改数据时SQLServer就不得不做更多的操作。因此,你应该避免在太宽的列上添加索引。索引越窄,性能越快。

另外,复合索引,包括两个或更多的列,也可能出现同样潜在的问题。通常要尽可能的避免复合索引。数据库使用复合索引越多,常常意味着数据库的设计有缺陷。

不可能总是避免宽索引或复合索引,但不得不用时,确信对你的选择做过仔细的评估并且没有其他的办法帮助提高性能。

连接的表的连接列上是否有适当的索引?

基本上,为了最好的性能,表里用来连接的列上都应该建索引。这是直接了当的建议,也是相当显而易见的,但为了最优的JOIN性能监控索引却是不容易的,因为为了全面的性能监控你必须熟悉数据库里所有执行的连接。

当创建主外键关系(通常用来JOIN的)时,很多人都忘记了主键列上会自动创建索引而外键列上不会自动创建,外键列上必须手动创建。

由于经常忘记,作为监控的一部分,你要分辨出表的所有主外键关系并检查每一个外键列上是否有正确的索引。

除此之外,你也能使用索引调优向导帮助分辨出丢失的连接索引,但我发现向导不总是能为连接表分辨出丢失的索引。说穿了,除非你知道数据库里通常运行连接的类型,否则是很难分辨出索引建在哪些列上能获得帮助。

索引是否足够唯一到有用?

仅仅因为一个表有一个或更多的索引并不意味着SQLServer查询分析器会用到它们。在它们被使用之前,查询优化器不得不考虑它们是否有用。如果表的列上不是至少有95%是唯一的,那么查询优化器最可能不用这个列上的非聚集索引。因此,不要给那些没有95%唯一值的列上添加非聚集索引。例如,一个只有"yes"和"no"的列上不是至少95%都是唯一的,在这列上创建索引基本上永远不会得到使用,我们已经知道这对性能有很大的拖累。

作为监控的一部分,考虑在表上目测数据。换句话说,查看表里的数据,再看看索引的那些列。通常,列是否可选来做索引是非常显而易见的。如果你注意到数据都是男或女,是或否等等,那么这些数据不可选来做索引,并且它们上面的任何索引都将浪费空间并影响性能。

覆盖索引是否带来了好处?

覆盖索引是复合索引的一种形式,包括查询里SELECT、JOIN、WHERE语句引用的所有的列。因此,索引包含了你要查询的数据,SQLServer不必去表里查找实际的数据了,这样减少了逻辑或物理I/O,从而提升性能。当非覆盖的复合索引不能提升性能时,覆盖索引就派上用场了,大多数情况下,它确实能提升查询的性能。

分辨出覆盖索引在什么地方最有用是很困难的。虽然索引调优向导能有所帮助,但它仍会丢失大量的找到覆盖索引有用的地方的机会。另外,唯一的方法就是小心检查你数据库里运行的所有查询,当然这几乎是不可能的,除非你真的有时间且没有其他更好的事情去做。

在这点上,你监控的目的本身不是找出新的覆盖索引,而是理解它们以便你在你的环境里遇到它们有用的地方时能从中获得好处。

索引重建的频率是多少?

随着时间的推移,索引会出现碎片,这会引起SQLServer访问它们时降低性能。唯一的解决方法就是定期整理数据库里所有索引的碎片。有几种不同的方法来整理,怎样去整理不会在这儿讨论,这个在SQLServer的帮助文档里有,本网站以后也会介绍。

你监控的目的是找出正在监控的数据库的索引是否在定期的整理碎片。整理碎片的频率从每天每周到每月不等,依赖于修改的频率和数据库的大小。如果数据库每天要进行很多修改,那么碎片整理应该更频繁的执行。如果数据库很大,这意味着碎片整理要花更长的时间,因此由于碎片整理过程占用太多的资源从而影响用户的使用,所以不能太频繁的整理碎片。作为监控的一部分,你要评估碎片产生的频率,找到最佳的频率。

至少,如果索引目前没有重建,而它们又需要重建,作为监控的一部分,你需要确认一些适当的索引重建计划。

索引的填充因子是多少?

和索引重建最相关的是填充因子。当创建一个新索引,或重建一个存在的索引时,你可以指定一个填充因子,它是在索引创建时索引里的数据页被填充的数量。填充因子设置为100意味着每个索引页100%填满,50%意味着每个索引页50%填满。

如果你创建一个填充因子为100的聚集索引(在一个非单调递增的列上),那意味着每当一个记录被插入(或修改)时,页拆分都会发生,因为在现存的页上没有这些数据的空间。很多的页拆分会降低SQLServer的性能。

举个例子:假定你刚刚用缺省的填充因子新创建了一个索引。当SQLServer创建它时,它把索引放在相邻的物理页面上,因为数据能够顺序的读所以这样会有最优的I/O访问。但当表随着INSERT、UPDATE、DELETE增加和改变时,发生了页拆分。当页拆分发生时,SQLServer必须在磁盘的某处分配一个新的页,这些新的页和最初的物理页不是连续的。因此,访问使用的是随机的I/O,而不是有顺序的I/O,这样访问索引页会变得更慢。

那么理想的填充因子是多少呢?它依赖于应用程序对SQLServer表的读和写的比率。首要的原则,按照下面的指导:
? 低更改的表(读写比率为100:1):100%的填充因子
? 高更改的表(写超过读):50-70%的填充因子
? 读写各一半的:80-90%的填充因子
在为应用程序找到最优的填充因子前也不得不进行试验。不要假定一个低的填充因子总比高的好。低的填充因子会减少页拆分,它也增加了SQLServer查询期间读的页数量,从而减少性能。太低的填充因子不仅增加I/O开销,也影响缓存。当数据页从磁盘移到缓存中时,整个页(包括空的空间)都移到缓存中。所以填充因子越低,不得不移到SQLServer缓存中的页面就越多,意味着同时为其他重要数据页驻留的空间就少,从而降低性能。

如果你没有指定填充因子,缺省的填充因子时0,意味着100%的填充因子(索引的叶页100%的填满,但索引的中间页有预留的空间)。

作为监控的一部分,你要决定新建索引或重建索引时的填充因子是多少。事实上,除了只读数据库,所有的情况,缺省值0都是不适合的。相反,你想要一个填充因子保留合适的自由空间,按照上面的讨论来做

SQLServer应用程序和TSQL性能监控列表

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址

性能监控列表
TSQL监控列表 你的答案
TSQL代码返回了不必要的数据吗?
在不必要的地方使用了游标吗?
UNION和UNION SELECT使用得当吗?
SELECT DISTINCT使用得当吗?
WHERE子句是可SAGE的吗?
在不必要的时候使用了临时表吗?
查询里的提示使用得当吗?
使用了不必要的视图吗?
只要可能就用存储过程了吗?
存储过程里使用了SET NOCOUNT ON吗?
你的任何一个存储过程是以sp_开头的吗?
所有的存储过程的拥有者是DBO吗?引用的形式是databaseowner.objectname吗?
你正为引用完整性而使用约束和触发器吗?
事务是尽可能的短吗?

应用程序监控列表
应用程序使用存储过程(一批TSQL代码)和使用对象模型如ADO来与SQLServer通信吗?
应用程序使用什么模式和SQLServer通信:DB-LIB、DAO、RDO、ADO还是.NET?
应用程序使用ODBC还是OLEDB和SQLServer通信?
应用程序利用了连接池吗?
应用程序是适当的打开、重用、关闭连接的吗?
传给SQLServer的TSQL代码是最优化的还是普通的SQL?
应用程序从SQLServer返回了不必要的数据吗?
当用户正修改数据时应用程序保持事务打开吗?

在上面的表里输入你的结果

应用程序和TSQL代码极大的影响着SQLServer的性能

在所有能影响SQLServer性能中,被用来访问SQLServer数据的应用程序代码,包括TSQL代码是潜在最影响性能的。但不幸的是,这些是很多DBA都不能直接控制的。因此,当对基于SQLServer的应用程序调优时通常都忽略了这些。

和这一系列文章前面的那些文章一样,本监控的目的也是找出访问SQLServer数据的应用程序和TSQL代码里容易的性能相关的问题。除了这里列出的提示,还有大量更多的影响SQLServer性能的因素,但这里列出的是一个好的开端。

当然,如果你在使用第三方软件,那么这部分性能监控不影响你因为你没有做太多关于代码的事。但如果你开发了自己的应用程序或应用程序事内部开发的,那么你应该采用这部分SQLServer的性能监控。

当你回顾下面监控项目的讨论时,你很快会发现分辨它们中的一些问题,甚至纠正它们不是一件小的任务。因此,更好的方法是心里带着这些性能提示来开发应用程序而不是在应用程序开发完后去纠正。当开发新的应用程序的时候你可以把这篇文章放在左右以便开发应用程序时能第一时间看到相关的性能提示。

TSQL监控列表

TSQL代码返回了不必要的数据吗?

SQLServer返回的数据越少,操作需要的资源也越少,可以帮助全面提升SQLServer性能。这听起来是显而易见的,但这种情形引起的性能问题我一而再再而三的看到。

开发人员在从SQLServer返回数据时结果返回更多不必要的数据,下面是他们常犯的一些错误:
? 缺少WHERE子句,除非你要返回表里所有的数据,而这种情况几乎很少,在减少返回行的数量时使用WHERE子句是必要的。
? 作为上面建议的补充,WHERE子句应尽可能的具有可选性。例如,如果你仅需返回特定日期的记录,而不是返回月或年的所有记录。设计WHERE语句以便能正好仅仅返回需要的那些行,而不要有额外的行。
? 在SELECT语句里,仅仅包括需要的那些列,而不是所有列。同样,当最可能要返回需要的更多的行时,不是使用SELECT *。
? 我将在这页的后面再次提及该条目,但这里它也适用。不要对视图执行SELECT,相反,绕过视图直接从需要的表里获取数据。原因是许多视图(当然不是全部)返回比SELECT语句所需更多的数据,而SELECT语句终止返回比需要更多的数据。
万一你不了解它们,下面一些性能问题是由返回不必要的数据引起的:有时,返回太多的数据会强迫查询优化器执行表扫描而不是索引查找;读数据需要额外的I/O开销;缓存空间也浪费了,本来可以被SQLServer为其他目的更好使用的;产生不必要的网络流量;在客户端,内存不得不存储这些额外的数据,而这部分内存可以被其他应用更好的使用;等等。

在不必要的地方使用了游标吗?

任何一种游标都会降低SQLServer性能。有些情况不能避免,大多数情况可以避免。所以如果你的应用程序目前正在使用TSQL游标,看看这些代码是否能够重写以避免它们。

如果你需要一行一行的执行操作,考虑下边这些选项中的一个或多个来代替游标的使用:
? 使用临时表
? 使用WHILE循环
? 使用派生表
? 使用相关子查询
? 使用CASE语句
? 使用多个查询
上面每一个都能取代游标并且执行更快。 如果你不能避免使用游标,至少试着提高它们的速度。找出加速游标的方法在其他文章会有介绍。

UNION和UNION SELECT使用得当吗?

许多人没完全理解UNION和UNION SELECT是怎样工作的,因此,结果浪费了大量不必要的SQLServer资源.当使用UNION时,它相当于在结果集上执行SELECT DISTINCT。换句话说,UNION将联合两个相类似的记录集,然后搜索潜在的重复的记录并排重。如果这是你的目的,那么使用UNION是正确的。

但如果你使用UNION联合的两个记录集没有重复记录,那么使用UNION会浪费资源,因为它要寻找重复记录,即使它们不存在。所以如果你知道你要联合的记录集里没有重复,那么你要使用UNION ALL,而不是UNION。UNION ALL联合记录集,但不搜索重复记录,这样减少SQLServer资源的使用,从而全面提升性能。

SELECT DISTINCT使用得当吗?

我曾经注意到一些开发人员机械地在SELECT语句里添加DISTINCT,而不论需要与否。从才能的角度看,DISTINCT子句仅在特定功能的时候使用,即从记录集中排除重复记录的时候。这是因为DISTINCT子句要求存储结果集然后去重,这样增加SQLServer有用资源的使用。当然,如果你需要去做,那就只有去做了。当如果你知道SELECT语句将从不返回重复记录,那么使用DISTINCT语句对SQLServer资源不必要的浪费。

WHERE子句是可SAGE的吗?

术语"sargable"(实际上是一个捏造的词)来源于"Search ARGument"(搜索参数)的首字母拼成的"SARG",它是指WHERE子句里列和常量的比较。如果WHERE子句是sargable(可SARG的),这意味着它能利用索引加速查询的完成。如果WHERE子句不是可SARG的,这意味着WHERE子句不能利用索引(或至少部分不能利用),相反执行的是表或索引扫描,这会引起查询的性能下降。

在WHERE子句里不可SARG的搜索条件如"IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE"和"LIKE '%500'"通常(但不总是)会阻止查询优化器使用索引执行搜索。另外在列上使用包括函数的表达式,两边都使用相同列的表达式,或和一个列(不是常量)比较的表达式,都是不可SARG的。

并不是每一个不可SARG的WHERE子句都注定要表扫描。如果WHERE子句包括两个可SARG和一个不可SARG的子句,那么至少可SARG的子句能使用索引(如果存在的话)帮助快速访问数据。

大多数情况下,如果表上有包括查询里所有SELECT、JOIN、WHERE子句用到的列的覆盖索引,那么覆盖索引能够代替表扫描去返回查询的数据,即使它有不可SARG的WHERE子句。但请记住覆盖索引尤其自身的缺陷,如此经常产生宽索引会增加读时的磁盘I/O。

某些情况下,可以把不可SARG的WHERE子句重写成可SARG的子句。例如:

WHERE SUBSTRING(firstname,1,1) = 'm'

可以写成:

WHERE firstname like 'm%'

这两个WHERE子句有相同的结果,但第一个是不可SARG的(因为使用了函数)将运行得慢些,而第二个是可SARG的,将运行得快些。

如果你不知道特定的WHERE子句是不是可SARG的,在查询分析器里检查查询执行计划。这样做,你能很快的知道查询是使用了索引还是表扫描来返回的数据。

仔细分析,机灵思考,许多不可SARG的查询能写成可SARG的查询。

在不必要的时候使用了临时表吗?

临时表有很多特殊的用途,象用来替代游标,不过它们仍能引起性能问题,如果这个问题能消除,SQLServer将执行得更快。例如,有几种消除临时表、减少开销、提升性能得方法。消除临时表的方法如下:
? 重写代码以便你要完成的操作能使用标准的查询或存储过程去做
? 使用派生表
? 使用SQLServer2000的表数据类型。这些不一定更快,需要测试
? 考虑使用关联的子查询
? 使用永久表代替
? 使用UNION语句模仿临时表
每一个选项都常常能用来帮助消除你TSQL代码里的临时表。

查询里的提示使用得当吗?

通常说来,SQLServer查询优化器能很好的完成优化查询的工作。但很少的情况下,查询优化器会失败,为了得到查询最好的性能需要使用查询提示来代替查询优化器。

提示在某些情况下是有用的,不过它们也是危险的。因此使用提示要特别小心。

最大的问题之一是遇到大量使用提示的一些代码,尤其是这些代码是在SQLServer6.5或7.0下写的,现在要转到2000下。大多数情况下,SQLServer以前版本选需要的提示在新版本里不再适用,使用它们实际上是影响而不是提示性能。

另一种情形是应用程序最初做出来的时候也许提示早期是有用的,但随着时间的推移,存储的数据本身已发生了变化,曾经有用的提示也许对新数据不再适用,找出有潜在性能危险并不再适用的提示。

在这两种情况里,一个好的方法是周期性的重新评估使用的查询提示好处。你也许发现目前的提示根本没有好处,事实上是影响了性能。找出这个唯一的方法是在查询分析器里测试它们看看实际发生了什么,然后基于你的发现决定是否继续使用它们。
使用了不必要的视图吗?

视图最大的用途是处理安全相关的问题,而不是一些懒惰的开发人员用来存储经常使用的查询的方法。例如,如果你需要允许用户特定访问SQLServer的数据,那么你也许可以考虑为用户(或组)创建一个视图,然后给用户访问视图而不是基表的权限。另一方面,在应用程序里,从视图选择数据没有好的理由,相反,使用TSQL代码直接从表里选择真正需要的数据。视图增加不必要的开销,大多数情况下,返回更多不必要的数据,增加不必要的开销。

例如,假定有一个视图从两个连接表里返回10列。你想要从视图里使用SELECT语句返回7列。实际上发生的情况是查询基于的视图先运行,返回数据,然后你的查询针对这些数据运行。既然你仅需要7列,而不是视图返回的10列,更多不必要的数据被返回。浪费SQLServer的资源。在你的应用程序里遵循下面的规则:总是直接访问基表,而不要通过视图。

只要可能就用存储过程了吗?

存储过程为开发人员提供了很多好处,包括:
? 减少网络流量和响应时间,提升应用程序性能。例如,通过网络发送一个存储过程调用,而不是发送500行的TSQL将更快,资源使用更少。
? 存储过程执行计划能够重用,驻留在SQLServer内存的缓存里,减少服务器开销。
? 客户端执行请求更有效率。例如,如果应用程序需要插入大量的二进制值到一个image数据列而不使用存储过程,它必须转化二进制为字符串(大小会增加一倍),然后发送给SQLServer。当SQLServer接收到后,它必须把字符串值转回二进制格式。大量的浪费开销。存储过程能消除这个问题通过将应用程序传给SQLServer的二进制格式作为参数,从而减少开销提升性能。
? 存储过程帮助提供代码重用。虽然这些不直接提升应用程序的性能,通过减少代码量和减少调试时间来提升开发人员的效率。
? 存储过程能封装逻辑。你能够改变存储过程代码而不影响客户端(假定你保持参数相同也不移除任何结果集的列)。这节约开发人员的时间。
? 存储过程为你的数据提供更好的安全性。如果你仅使用存储过程,你可以移除直接对表的SELECT、INSERT、UPDATE和DELETE权限从而强迫开发人员使用存储过程访问数据。这会节约DBA的时间。
作为首要的常规,所有的TSQL代码都应该通过存储过程调用。

存储过程里使用了SET NOCOUNT ON吗?

缺省地,每次存储过程执行时,一个消息会从服务端发给客户端以显示存储过程影响的行数。这些信息对客户端来说很少有用。通过关闭这个缺省值,你能减少在服务端和客户端的网络流量,帮助全面提升服务器和应用程序的性能。 为了关闭存储过程级的这个特点,在每个存储过程的开头包含下面语句:

SET NOCOUNT ON

该语句应该包括在你写的每一个存储过程里。

你的任何一个存储过程是以sp_开头的吗?

如果你创建的存储过程不是运行在Master数据库里,不要使用以sp_为前缀的名称。这个特别的前缀是为系统存储过程保留的。尽管使用这个前缀不会禁止用户定义的存储过程的运行,但会稍微降低一些执行效率。

这是因为SQLServer在执行以sp_为前缀的任何一个存储过程时缺省地首先试图在Master数据库里寻找,尽管那儿没有,这就浪费了寻找存储过程的时间。

如果SQLServer在Master数据库里不能找到存储过程,那么接下来会将存储过程的拥有者作为DBO去解析。如果存储过程在目前的数据库里,那么它会执行。为了避免不必要的延迟,不要用前缀为sp_命名你的任何一个存储过程。

所有的存储过程的拥有者是DBO吗?引用的形式是databaseowner.objectname吗?

为了最好的性能,同一个存储过程里调用的所有对象的拥有者都应该相同,DBO更适宜。如果不是那样,即对象名相同而拥有者不同,那么SQLServer必须执行名称判断。当发生这样的情形时,SQLServer不能使用存储过程里在内存里的执行计划,相反,它必须重新编译存储过程,从而影响性能。

当从应用程序里调用存储过程时,使用分隔符名称来调用也是重要的。如:

EXEC dbo.myProcedure

代替:

EXEC myProcedure

为何?有两个原因,其中一个和性能有关。首先,使用完全有分隔符的名称有助于消除那些和你要运行的存储过程有潜在的混淆,有助于禁止BUG和潜在的问题。但更重要的是,这样做SQLServer能更直接的访问存储过程执行计划,而不是轮流访问,从而加速了存储过程的性能。当然性能提升很小,但如果你的服务器没小时要运行成千上万或更多的存储过程,这些节约的小段时间加起来就很可观了。

你正为引用完整性而使用约束和触发器吗?

在你的数据库里不要执行多余的完整性特点。例如,如果你正使用主键和外键约束来强迫引用完整性,不要添加触发器来实现相同的功能而增加不必要的开销。同样既使用约束又使用默认值或既使用约束又使用规则也会执行多余的工作。虽然这听起来显而易见,找出SQLServer数据库里这些问题并非不寻常的。

事务是尽可能的短吗?

保持TSQL事务尽可能的短。这会帮助减少锁(所有类型的锁)的数量,有助于全面提升SQLServer的性能。如果有经验,你也许要将长事务分成更小的事务组。关于禁止不必要的锁将在其他文章中介绍。

应用程序监控列表

应用程序使用存储过程(一批TSQL代码)和使用对象模型如ADO来与SQLServer通信吗?

当应用程序需要和SQLServer通信时,本质上有3种选择:使用存储过程、使用一串TSQL代码或者使用对象模型的属性和方法。从性能的角度来看,最有效率的是存储过程,最没效率是对象模型的属性和方法。理论上,应用程序应该仅使用存储过程来访问SQLServer。

存储过程的好处在本文的前面已有所介绍,所以在这里不再重复。紧接着第二个方法是发送给SQLServer一串TSQL代码。如果写得正确,查询执行计划会自动重用,有助于提升性能,尽管你得不到存储过程的一些好处如减少网络流量。使用对象模型的属性和方法的问题自爱欲它们添加了额外的代码层,从而降低了通信。另外,常常但不总是,被这些TSQL代码创建的属性和方法不是很有效率的,更影响性能。

应用程序使用什么模式和SQLServer通信:DB-LIB、DAO、RDO、ADO还是.NET?

为了和SQLServer通信,所以的应用程序都需要使用数据访问库(MDAC组件),有几个库可供选择。为了最优的性能,.NET是首选。如果还没有使用.NET工具,那么接下来最好的选择是ADO。在所有的环境下,避免使用DB-LIB(停用但仍支持)和DAO,两个都很慢。

应用程序使用ODBC还是OLEDB和SQLServer通信?

如果你在访问SQLServer数据库时要在ODBC和OLEDB之间选择,那么选择OLEDB,通常它更快。另外,使用OLEDB允许使用很少的DSN连接 ,这样连接维护比基于ODBC、DSN的连接更快。

应用程序利用了连接池吗?

尝试使用连接池去减少SQLServer的连接开销。连接池是指客户端应用程序在连接SQLServer时不必在有连接需求时每次都建立建立新的连接 而使用以前存在的连接的术语。这会减少SQLServer的开销,加速连接。

微软提供了两种类型的连接池。通过ODBC的连接池,可以使用ODBC数据源管理器配置、注册或调用应用程序。通过OLEDB的资源池,可以使用应用程序连接字符串配置OLDB API或注册。

要么连接池要么资源池运行相同的连接。相同的连接不能两种池都使用。同样,连接池要工作得有效率,那么连接要重用,而安全实现又很麻烦。对于重用的连接,须使用相同的安全环境,否则会自动打开另一个连接,连接池会不起作用。本质上,这意味着所有从应用程序连接到SQLServer的用户必须共享相同的用户帐号。如果不是,当它们需要通过应用程序访问SQLServer时,每个用户将自动打开一个新连接。

为了最大化性能,当连接到SQLServer时将几乎总是要利用一个或另一个池的方法。

应用程序是适当的打开、重用、关闭连接的吗?

一般说来,SQLServer的连接仅在需要的时候打开、使用、然后立即由应用程序关掉。假定你正在使用连接池和适当的安全模型,如果连接目前不可用会怎样呢?它将被创建。一旦连接被应用程序关闭,它将继续打开(尽管应用程序认为它是关闭的),当需要重用时连接是可用的。

减少实际连接打开和关闭的频率能减少SQLServer的开销。同样,应用程序快速的打开和关闭连接,这些都允许形成连接池来更有效的重用,也帮助减少开销,提升性能。

传给SQLServer的TSQL代码是最优化的还是普通的SQL?

一些应用程序由于设计成使用多个数据库,就使用ANSI SQL替代TSQL访问SQLServer数据。虽然这样做能更容易的连接到各种不同的数据库,但也影响了性能。TSQL提供了ANSI SQL里没有的一些特殊的代码,这些为性能提供了好处。理论上,为了更好的性能,应该使用TSQL来访问SQLServer而不是普通的ANSI SQL。

应用程序从SQLServer返回了不必要的数据吗?

这和TSQL审核建议里的一个是相同的。一些应用程序,特别是那些允许用户浏览数据的程序,给用户返回太多的数据常会引起应用程序放宽对用户有利的那些数据的限制。例如,我曾经看到应用程序实质上返回了表或视图的所有行,对应用程序而言,还要排序数据以便用户的浏览。如果行数量不大,那没问题。但如果行数量巨大,例如100000行或更多,那么SQLServer在返回这些数据时不得不进行巨大数量的操作(通常是表扫描),网络也阻塞了。没有用户会使用所有的数据。应用程序应该设计成仅返回用户当时真正需要的数据,而不要多一个字节。

另一个返回太多数据的例子是应用程序允许用户执行标准的查询。如果你必须允许用户选择它们自己的标准,重要的一点是禁止偶然返回太多的数据。例如,可以在SELECT语句里使用TOP子句,或者在WHERE子句里包括一些缺省的参数来禁止用户返回表里的所有行。

返回不必要的数据是非常浪费资源的,也是很容易避免的问题只需稍微计划计划。

当用户正修改数据时应用程序保持事务打开吗?

这和TSQL审核建议里的一个是相同的。大多数应用程序有一个建议:允许用户查找数据,然后更新。这样做成功的关键是允许用户这样做的时候,确保没有保持连接打开--更新的时候记录会被锁住。如果你打开了连接,你会创建不必要的长时间的阻塞锁,从而影响性能。

理论上,从应用程序的观点来看,一旦用户执行了记录更新,应用程序将打开连接,选择记录,然后关闭连接。现在记录出现在应用程序屏幕上。一旦用户更新了,那么应用程序需要重新打开连接,查看修改过的记录(假定它是更新了),然后关闭连接。事务保持尽可能的短是很重要的。

SQLServer数据库作业性能监控列表

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址
SQLServer作业监控列表 你的答案
运行了任何不必要的作业吗?
作业调度是在服务器不忙的时候吗?
同一台服务器上的SQLServer作业有交迭吗?
任何非SQLServer的作业有交迭吗?
作业运行的TSQL是最优化的吗?
检查作业运行了多长时间吗?
目前的作业有替代方法吗?

在上表输入你的结果。

如果你不仔细,SQLServer作业有可能影响性能

事实上每个SQLServer都运行一个或更多日常的作业。更可能运行很多每周一次的作业。不幸的是,大多数DBA创建了作业,然后就忘掉了它们,当然除非作业出了问题。但如果作业没出现问题,一天一天的运行下去的话,大多数作业都会被忘掉。

就像任何应用程序可能影响SQLServer性能一样,作业也有可能。那些有设计得不好的代码的作业,或者在糟糕的时间运行的作业,能引起SQLServer重大的损伤。因此,将SQLServer作业作为性能监控的一部分指很重要的。

本节将着眼于如何分辨,纠正潜在的与作业相关的性能问题。

运行了任何不必要的作业吗?

创建一个完成特定任务的作业是很容易的,然而当任务不再需要时忘掉移除它们也是经常发生的事。例如,你也许需要创建一个作业去从几个表里每晚移动数据到另一个表里,用来产生报表。但如果报表不再有用,也就不再有任何需要运行的作业,所以应该移除它们以减少开销。问题是在作业和报表之间没有直接连接,所以如果报表不再有用,很容易忘记移除作业。

作为监控的一部分,检查运行在服务器上的每一个作业,看看作业是否真的需要。如果不需要就移除它。

沿着这个思路,看看有重复的作业没有。例如,我曾经看到DBA新手使用维护向导在SQLServer里创建了作业,而没有真正意识到它们做了什么。然后他们又手工添加了一些与维护向导创建的一个或更多作业相同的作业。同样的事情做了两次大量的浪费了SQLServer的资源。

作业调度是在服务器不忙的时候吗?

当你检查SQLServer里的每一个作业时,看看它们的运行时间。要是作业不必要运行在特定的时间,尽量在SQLServer不忙的时候调度,如晚上或周末,取决于你的环境。

如果你不能确认SQLServer什么时候是空闲的,用性能监视器做一个超过一周的监控日志。这将提供给足够的数据以分辨出能运行非时间敏感的作业的空闲时间。

同一台服务器上的SQLServer作业有交迭吗?

这个问题比大多数DBA意识到的要大得多,特别是当SQLServer有很多很多的作业时。当SQLServer上有很多活动时,如果作业能尽可能的随时间分布则是理想的,不要所有的作业都在同一刻运行。例如,如果你的SQLServer有10个数据库,你要为每个数据库创建备份的作业,更好的方法是一次运行一个,而不是在同一时间运行所有的作业。

虽然你能通过企业管理器查看作业运行的时长,但没有一个容易的方法来一个接一个(给每一个作业足够的时间去完成)的手工调度作业,以便它们不产生交迭。这也能做到,但对于有大量作业的服务器来说,你也许需要一个表格来列出所有的作业。作为一个选择你可以考虑使用第三方工具如SQL Sentry([url]www.SQLSentry.net[/url]),它允许你可视化地管理和查看你所有的作业,以确保这些作业没有交迭。

所以当你进行作业监控的时候,检查看看作业交迭情况,假定这是可能的。如果它们的确交迭了,尽量重新调度它们以禁止交迭,尽可能分散负载到大量空闲的时间。

任何非SQLServer的作业有交迭吗?

除了SQLServer作业外,你的服务器上也许有一些非SQLServer的作业。有些例子包括碎片整理或磁带备份作业而不是使用SQLServer调度。既然这些不使用SQLServer调度,它们也容易被忘记,你也许同时终止了一些作业的运行,就像终止SQLServer作业的运行一样。和SQLServer作业一样,如果你能在不同时间调度这些作业而不是在SQLServer作业运行的时候则是理想的。如果你需要这样做,在上面讨论的表格里加入这些作业。

作业运行的TSQL是最优化的吗?

就像应用程序、脚本里的代码一样,运行在作业里的TSQL也是需要优化的一部分。TSQL代码的优化将在其他地方做介绍,任何有关的索引也应该被添加以便帮助作业代码更有效率的运行。

所以对于每一个有TSQL代码的作业来说,你应该通过查询分析器运行它来查看执行计划,查找潜在的问题,也可以通过索引向导,查找潜在的索引以提升性能。

检查作业运行了多长时间吗?

我已经提过你能使用企业管理器来查看任何作业运行的时长。但我没有提及的是最好随时检查看看这个时长是否有大量的变化。例如,一个特定的作业正常情况下运行2分钟,但你发现一周有一次,在星期天,同样的作业花费了15分钟。作业时长发生了重大的改变是一个好的迹象表明作业和其他在SQLServer上运行的进程有冲突。如果你发现有这类问题,你需要更仔细的调查并分辨出出了什么问题,然后纠正它。

目前的作业有替代方法吗?

仅仅因为有作业要运行并不意味着它是手边完成任务的最好方法。评估每一个作业,然后决定是否有更好的方法来完成同样的工作。例如,或许写TSQL代码每晚执行导入比使用目前的DTS包更有效率。或者也许你正运行的作业,使用另外的调度程序去脱离SQLServer运行能更好。但记住关键的是,你目前的作业常常不是唯一的解决方法,有更好的可用的能减少服务器开销的解决方法,如果你花时间考虑一下的话。

使用Profiler找出低效的查询

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址

监控列表 你的答案
你分辨过所有长时间运行的查询吗?
对这些查询你区分优先次序了吗?
你重新查看过上面区分优先次序的查询的执行计划了吗?

在上表输入你的结果

第一步是分辨出长时间运行的查询

到SQLServer性能监控的这一步止,你应该已经能分辨出所有容易纠正的性能问题了。现在是着手处理更差的查询(包括存储过程)的时候了,那些比预期运行时间更长的占用大量SQLServer共享资源的查询和存储过程。

运行慢的查询执行要花费太长的时间。那么究竟多长才算长呢?这得由你决定。通常说来,我用5秒作为一个坎儿。换句话说,任何一个查询运行5秒或更少通常就算足够快了,而查询超过5秒就算长了。这是一个你不得不做出的武断的决定。在我工作的公司,报表开发人员要写大量的和我有不同标准的征对数据库的查询。他们考虑的时长为30秒。所以,第一步就是决定多长时间的查询才算长,然后在你的服务器性能监控期间使用这个作为你的标准。

我们不能无限制的调优查询。我们所能做的就是分辨出那些需要更多工作的查询,然后征对它们进行调优。如果有时间的话,为了全面提升SQLServer的性能,可以着眼于那些稍慢但仍然讨厌的查询。记住有些时候,无论你怎么努力调优一个特殊的查询,可能仅有一点或根本没有性能上的改善。

开始之前

对于这部分性能监控,你将使用SQLServer自带的事件探查器。本篇文章仅着眼于怎样进行性能监控,而不是工具的使用,所以假定你知道怎样使用事件探查器。如果你以前没有用过它,查看BOL以获得一些基本的帮助。

在你使用事件探查器捕捉你的SQLServer查询活动之前,记住下面的:
? 不要在你要监控的同一台服务器上运行事件探查器,这对服务器性能有一个明显的影响。相反,在另一个服务器或工作站上运行,然后在那儿收集数据。
? 当运行事件探查器时,不要选择比需要收集更多的数据。你收集的数据越多,用来收集它们而使用的资源就越多,这会降低性能。仅仅选择那些你真正需要的事件和数据列。我的建议是所收集的真正的要简短。
? 在一段典型的服务器运行时间内收集数据,即典型的3-4小时的时间。这也可以改变,依赖于你服务器繁忙的程度。如果你没有这样的时间,你可以通过一个典型的生产日的几个不同时间段来收集你需要的所有数据。
当你使用事件探查器时,你有两个选项去启动它。一个是使用GUI界面,或者如果你喜欢的话,可以使用内建的事件探查器系统存储过程。虽然使用GUI有点简单,但使用系统存储过程收集数据的开销稍微的少一些。本文将使用GUI界面。

收集什么数据

事件探查器允许你指定哪些事件需要捕捉,那些事件的哪些数据列需要捕捉。另外,你可以使用筛选来减少数据而仅要哪些分析需要的社会局。下面是我的建议:

要捕捉的事件
? Stored Procedures--RPC:Completed
? TSQL--SQL:BatchCompleted
你也许会惊讶怎么只有两个不同的事件需要捕捉:一个用来捕捉存储过程一个用来捕捉所有其他的TSQL查询。

需要捕捉的数据列
? Duration (数据需要通过duration来分组)
? Event Class
? DatabaseID (如果服务器上有多个数据库的话)
? TextData
? CPU
? Writes
? Reads
? StartTime (可选的)
? EndTime (可选的)
? ApplicationName (可选的)
? NTUserName (可选的)
? LoginName (可选的)
? SPID
你实际上要捕捉和查看的数据包括一些对你来说很重要的数据,特别是duration和TextData;一些就不那么重要了,但也有用,如ApplicationName和NTUserName。

用于筛选
? Duration > 5000 毫秒 (5秒)
? 不要收集系统事件
? 通过单独的数据库ID而不是一次所有的数据库都收集数据
? 其他适当的筛选
筛选被用来收集数据的数量,使用筛选越多,你能筛选掉的不重要的数据就越多。一般说来,我使用3个筛选,但其他的也能根据你的情形适当的使用 。其中最重要的是duration。我仅收集那些对我来说很重要的有足够duration的信息,正如已经讨论的那样。

收集数据

依赖于使用的筛选、运行事件探查器收集数据的时间、服务器繁忙程度,你可以收集大量的数据行。虽然你有几个选择,我建议你配置事件探查器保存数据到本地计算机的文件上(而不是你跟踪的服务器上)并且不设置文件的最大尺寸,相反,让文件按需增长。你要查看文件的增长量,万一它无法控制。大多数情况下,如果你使用了正确的筛选,文件大小会便于处理的。我建议使用一个大的文件因为如果你那样做的话很容易分辨出长时间运行的查询。

正如前面所述,在一个典型的生产期间收集你的跟踪文件,大约3-4小时为一期限。当收集数据后,可使用duration来分类,运行时间最长的查询出现在跟踪窗口的底部。当你收集数据的时候有兴趣的话可以看一会儿窗口。如果你喜欢,可以配置在适当的时候自动关闭事件探查器,也可以手动关闭。

一旦时间到跟踪停止了, 事件探查器的跟踪现在存在本地计算机的内存和磁盘上。现在你准备去分辨那些长时间运行的查询了。

分析数据

我猜你已经能分辨出所有在跟踪收集期间运行的超过你指定的duration的所有查询,不管是不是。所以如果你指定duration为5秒,那么你将只看到那些运行超过5秒的查询。根据定义,你捕捉的所有查询都需要调优。"什么!但捕捉到了500多个查询啊! 那可是一项大工程!"那并不是你想象的那么糟。大多数情况下,你捕捉的很多查询是重复的。换句话说,你可能在你的跟踪里一再地捕捉了同样的查询。所以,那些500多个捕捉到的查询也许仅仅只有10个或50个或100不重复的查询。另一方面,也许捕捉到的只是少数的查询,如果你够幸运的话。

无论是少数查询还是大量运行慢的查询,你接下来的工作是首先决定哪一个查询对你的分析和调优来说是最重要的。这需要你设置优先级,因为你可能没有足够的时间去分析所有的查询。

为了设置这些长时间运行的查询的优先级,你可能首先要着眼于那些运行最长的查询。但当你这么做时,要记住每个查询运行的频率。

例如,如果你指定一个特定的查询仅仅是为了生成报表而一个月只运行一次(碰巧在它运行的时候你捕捉到了),这个查询运行花了60秒,它可能没有那些运行花了10秒但1分钟运行了10次的查询的优先级高。换句话说,你需要平衡查询运行的时长和频率。谨记这一条:你需要分辨并设置那些花费最多SQLServer物理资源的查询的优先级。一旦你做完这件事,就可以准备分析和调优了。

通过查看执行计划分析查询

为了分析你捕捉到的已经设置优先级的查询,你需要把代码移到查询分析器里以便能查看执行计划,分析查询。本篇文章着重在监控,而不是分析,我们不会在这里花费时间去向你展示怎样分析特定的查询。这本身是一个很大的课题,将在其他地方做介绍。

为了分析你怎样移到代码到查询分析器里依赖于代码。如果你捕捉到的代码是TSQL,你可以剪切,然后直接在查询分析器里粘贴。但如果代码是在存储过程里,你不得不稍微多做一点工作,因为事件探查器不会显示存储过程里的代码,而仅显示存储过程的名称,包括传给它的所有参数。这样,为了在查询分析器里分析查询,你必须考虑到存储过程里,将代码复制粘贴到查询分析器里。然后,假定那儿也有一些参数了,你不得不手工更改代码以便它能带着参数运行而被事件探查器捕获。

现在耗时的杂事开始了,分析每一个查询的执行计划看看有没有能改善性能的查询需要调优。但是因为你已经分辨和设置这些查询的优先级可,所以你的时间将更有效率。

怎样最好的实现SQLServer的性能监控

--王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]
--原帖地址

最后是怎样进行SQLServer的性能监控

到目前为止,你已经进行了大量的阅读。在最后这篇关于SQLServer性能监控的文章里,我们将讲一些为了最好的实现SQLServer性能监控的最好的实践。在对你的SQLServer进行任何实际的性能监控之前你需要阅读这篇文章。

自定义性能监控

在这一点上,我假定你已经阅读了,或者至少浏览了所有监控步骤的建议。我猜你也许读了一些,但那些真正不适合于你。既然大部分的SQLServer安装稍微有点不同,那么这是有意义的。因此我建议你为你特定的环境自定义这个监控,添加或删除一些步骤使其更适合你的需求。

使用Word或Excel维护你的监控列表

当你对你的每一个SQLServer进行监控时,你需要一个方法去记录结果。当你有大量的选项时,从这一系列的文章里复制适合的监控列表到你的Word或Excel文档作为起点是比较快速的方法。你可能要为每个服务器创建一个单独的监控列表。如果你决定为你的监控表格使用Excel的话,你能输入所有的监控列表项目作为行,每一个监控的服务器作为单独的列。这样你能快速的查看每个SQLServer的结果。

设置SQLServer和数据库的优先级

如果你管理大量的SQLServer和数据库,你也许不知道从哪儿开始性能监控。理论上,你应该设置SQLServer和数据库的优先级,一些需要立即进行最多的性能监控,而其他的则不必进行那么多的监控。这会帮助你决定从哪儿开始。最可能的是,你将不会立即监控全部。相反,要在能监控的时候监控,按照从最重要到最不重要的顺序进行。

谨记性能监控的关键

当对SQLServer进行监控的时候 ,记住目的是分辨并纠正容易的问题。但是,正如你所料,你将可能也分辨出一些更难于解决的问题。为了帮助你更好的管理有限的时间,你现在需要着眼于那些容易的问题,把困难的问题留到容易的问题先解决完之后。所以在你执行监控和分辨问题时,按照难易程度分类设置它们的优先级,将困难的问题留待你有足够时间处理它们的时候。

不要过早行动

当你执行监控时,你可能会急于对偶然遇到的问题进行纠正和修改。大多数情况下,那样做可能不是问题。但理论上,最好先执行监控,然后基于你的发现,决定正式动手解决你分辨出的问题,然后系统地实现它们。

一个推荐步骤,但或许会招来很多疑问

理想情况下,如有很多的时间,在服务器上执行一个性能基准是一个好的想法,然后执行监控,做任何需要的更改,再执行另一个性能基准去看看有什么情况发生。这会立即让你知道你所做的是否有帮助,大多数情况下,没有做正确的事。虽然这个建议被强烈的推荐,也许从时间来看不很实际。但如果你有时间的话,应该认真考虑。

另一个推荐步骤,但或许也会招来很多疑问

在执行监控之后,你也许发现在单个的SQLServer上所有需要的更改仅只有一两个,但在其他SQLServer上,也许需要做一打的更改。如果有那么的更改要做,不要立刻全部实现它们,仅仅一次一个或几个的更改也许是一个明智的选择。这样,你能够看看每个或每批更改对服务器产生的效果。如果你一次做了很多的更改,那么遇到问题时,你将不会知道是由哪个更改引起的问题,这要求你回滚所有的更改,然后一个一个的测试它们直到找到问题所在为止。

这个建议不会有太多疑问

如果你要做更改的服务器是有紧要事务的生产服务器,你要对你做的更改倍加小心。理论上,你应该在生产服务器应用更改之前在测试用的SQLServer上测试所有的更改。如果你不实践,那么每次仅做一个更改,确信如果有任何问题你知道怎样回滚更改。另外,试着选取一天中不很忙的时候做更改,万一有问题的话。

有一个取消计划

你因监控而做出的大多数更改应该能够很容易的回滚。但一些也许不那么容易。在那些情况下,你需要有一个万一需要的取消计划。例如,在你做出任何关键的更改之前备份系统和用户数据库。那样,即使出现问题,你也能将你的服务器恢复到更改之前的状态。我不是吓唬你不要做更改,但你总应该有所准备。

记录所有更改

当你基于性能监控做出更改时,确定你对所有的更改做了记录。这样,即使后来有什么问题,你也能更容易的找出错误所在。最容易记录下你的更改的方法可能就是把它们添加到你的监控表格里,或者其他你用来收集监控信息的文档里。

每年都要执行SQLServer的性能监控

许多SQLServer(并非全部)随着时间而改变。设置改变,打了SP补丁,甚至数据也改变了。所有的这些都会影响性能。确定你SQLServer最优性能的最好方法是做一个手工的性能监控。

在完成一个监控并更改之后,接下来该做什么呢?

轻松一下?哦,不是。刚好相反。记住,这一系列的监控是为捕捉显而易见和容易纠正的SQLServer性能问题而设计的。一旦你做完这些,接下来,你要分辨和纠正更难于纠正的问题。前面所提及的性能监控,也许能分辨一些可能问题,而其他的问题你不得不在它们出现的时候发现它们。无论如何,你要尽可能的花费更多的时间分辨和纠正最初性能监控遇到的困难问题。但和其他事情一样,着眼于那些引起最大性能问题的问题,然后尽你许可的时间用你的方法去解决它们。祝你好运!

你可能感兴趣的:(怎样查出SQLServer的性能瓶颈)