数据库性能2

操作系统性能监控列表


性能监控列表

操作系统性能相关项

你的配置

操作系统版本

 

磁盘分区格式是NTFS5.0吗?

 

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

 

SP是否最新?

 

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

 

服务器是否是独立的服务器?

 

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

 

安全审计是否打开?

 

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

 

不必要的服务是否关闭?

 

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

 

是否使用杀毒软件?

 


在上表输入你的结果. 

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

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

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

SQLServer可以运行在NT4.0win2000Win2003上,这里将讨论作为最新版本操作系统的Win2003。对于NT4.0Win2000,将在其他的文章里进行介绍。 如果你想发挥SQLServer最佳的性能,你需要运行在Win2003上,它比20004.0提供了更多的性能改善,包括:

  • 更好利用Intel超线程CPU的能力。
  • 使用Intel芯片最多可支持32CPU 64G 的内存,使用Itanium芯片最多可支持64CPU 512G 的内存。
  • I/O通道和磁盘I/O性能得到充分提升的同时,减少了大量的I/O请求所需要的CPU资源。

如果你还没升级到2003,尽快升级吧。它会更快更容易的提升SQLServer的性能。

磁盘分区格式是NTFS 5.0?

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

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

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

SP是否最新?

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

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

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

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

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

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

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

安全审计是否打开?

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

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

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

不必要的服务是否关闭?

为了最佳性能,关闭Win20002003系统任何一个不需要的服务。这既节约了内存也节约了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数据库设置性能列表


性能监控列表

数据库配置选项 

缺省值 

当前值 

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

这样有个问题就是:如果数据库被频繁的访问(这是经常的情况),那么数据库会不断的关闭重新打开,这样应用程序或用户在连接时会很大的影响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 Server512字节)是不同的尺寸,可能在电源故障或者磁盘驱动、物理磁盘问题时数据库会变得不完整。

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

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

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

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

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

查看数据库配置设置

这一节我们将只查看三个数据库配置设置,检查它们是怎样影响性能的。查看它们最好的方法是用企业管理器,参考下面的步骤(这些步骤适合于SQLServer2000):

  • 在企业管理器里,显示你的服务器里所有的数据库
  • 右击你要查看的数据库,选择属性
  • 从属性对话框里,选择选项标签查看兼容级别,选择数据文件标签查看数据库自动增长设置,选择事务日志标签查看事务日志自动增长设置。

让我们看看三个相关数据库配置设置的每一个。 

Compatibility Level

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

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

SQLServer7.0的兼容级别是702000的兼容级别是80 

Database and Transaction Log Auto Grow

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

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

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

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

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

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

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

 

SQLServer数据库索引性能监控列表


索引性能监控列表

索引列表

你的答案

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

 

每个数据库里的每个表是否有聚集索引?

 

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

 

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

 

索引是否太宽?

 

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

 

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

 

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

 

索引重建的频率是多少?

 

索引的填充因子是多少?

 

输入你的结果到上表。 

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

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

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

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

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

正如你已经看到的,我上面提供的审核列表不是很长。这是故意的。记住,这一系列关于性能监控的文章的目的是为了分辨容易和显而易见的性能问题,不是找出全部。上面列出来的将使你走很长的路去分辨和纠正容易的与索引相关的性能问题。一旦你掌握了它们,就可以更上一层楼了。例如,本网站上有很多索引相关的提示,大部分都很高级,比如下面的主题:

  • 普通索引
  • 聚集索引
  • 复合索引
  • 覆盖索引
  • 非聚集索引
  • 重建索引
  • 索引调优向导

如果你还没有做过的话,你需要复习这些提示的网页。

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

微软在SQLServer7.02000里给我们最好的工具就是之一就是索引调优向导。它不是一个完美的工具,但它确实能帮助你分辨存在的索引是否正被使用,同时提供能加快查询的新索引。如果你正使用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;选择所有被用来调优的表。通过选择这些选项,索引调优向导将进行彻底的工作,尽管要花费几个小时才能完成,这依赖于跟踪文件的大小和你执行分析的硬件的速度。注:这些只针对SQLServer2000SQLServer7.0稍微有些不同。
  • 一旦分析完成,向导也许没有任何建议,也许建议删除一个或更多的索引,或者建议添加一个或更多的索引,或者建议既添加也删除。你需要在采纳建议之前小心评估它们。例如,向导也许建议删除一个特殊的索引,但你知道该索引是真正需要的。那么当你知道这不是一个好想法可为什么向导建议删除呢?这是因为向导没有分析在跟踪文件(仅仅是一个抽样而已)里发现的每一个查询,加之你的抽样跟踪数据可能没有包括需要那个索引的查询。这种情况下,向导也许建议删除该索引,即使这不是一个好的建议。一旦你检查到一个索引是不需要的,你应该删除它。
  • 如果向导建议添加新的索引,那么你要评估它们,也要和目前表上存在的索引比较看看它们是否有意义,会不会引起潜在的新的问题。例如,一个建议的索引或许能帮助一部分查询,但它也可能降低每小时成千上万次的INSERT操作。向导不知道这些,你必须决定哪个更重要,一些查询运行快了点而INSERT去慢了,反之亦然。
  • 最后,即使索引调优向导没有任何新索引的建议,这也不意味着新索引是不需要的,仅仅根据跟踪数据来分析可能不会有任何建议。为了更好的帮助分辨出需要的索引。你要考虑好几天运行多个跟踪以便得到更多的抽样数据。即使那样,索引调优向导也不能找出全部需要的索引,但它将找出所有显而易见需要的索引。

一旦你完成分析并根据建议做出了更改,我建议你再次跟踪分析以便看看你的更改是否有效果。谨记索引调优向导分析不是一蹴而就的事情。随着时间的推移数据库的数据发生了潜在的变化,随着一起变化的还有查询的类型。所以,作为一个要点:定期的对服务器进行跟踪和分析以保持定期的优化。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

索引是否太宽?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

索引重建的频率是多少?

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

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

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

索引的填充因子是多少?

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

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

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

那么理想的填充因子是多少呢?它依赖于应用程序对SQLServer表的读和写的比率。首要的原则,按照下面的指导:

  • 低更改的表(读写比率为1001):100%的填充因子
  • 高更改的表(写超过读):50-70%的填充因子
  • 读写各一半的:80-90%的填充因子

在为应用程序找到最优的填充因子前也不得不进行试验。不要假定一个低的填充因子总比高的好。低的填充因子会减少页拆分,它也增加了SQLServer查询期间读的页数量,从而减少性能。太低的填充因子不仅增加I/O开销,也影响缓存。当数据页从磁盘移到缓存中时,整个页(包括空的空间)都移到缓存中。所以填充因子越低,不得不移到SQLServer缓存中的页面就越多,意味着同时为其他重要数据页驻留的空间就少,从而降低性能。

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

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

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

性能监控列表

TSQL监控列表 

你的答案 

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

 

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

 

UNIONUNION SELECT使用得当吗? 

 

SELECT DISTINCT使用得当吗? 

 

WHERE子句是可SAGE的吗? 

 

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

 

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

 

使用了不必要的视图吗? 

 

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

 

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

 

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

 

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

 

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

 

事务是尽可能的短吗? 

 

 

 

应用程序监控列表 

 

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

   

应用程序使用什么模式和SQLServer通信:DB-LIBDAORDOADO还是.NET 

   

应用程序使用ODBC还是OLEDBSQLServer通信? 

 

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

   

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

   

传给SQLServerTSQL代码是最优化的还是普通的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语句
  • 使用多个查询

上面每一个都能取代游标并且执行更快。 如果你不能避免使用游标,至少试着提高它们的速度。找出加速游标的方法在其他文章会有介绍。 

UNIONUNION SELECT使用得当吗?

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

如果你使用UNION联合的两个记录集没有重复记录,那么使用UNION会浪费资源,因为它要寻找重复记录,即使它们不存在。所以如果你知道你要联合的记 录集里没有重复,那么你要使用UNION ALL,而不是UNIONUNION 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的。

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

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

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

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

可以写成:

WHERE firstname like 'm%'

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

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

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

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

临时表有很多特殊的用途,用来替代游标,不过它们仍能引起性能问题,如果这个问题能消除,SQLServer将执行得更快。例如,有几种消除临时表、减少开销、提升性能得方法。消除临时表的方法如下:

  • 重写代码以便你要完成的操作能使用标准的查询或存储过程去做
  • 使用派生表
  • 使用SQLServer2000的表数据类型。这些不一定更快,需要测试
  • 考虑使用关联的子查询
  • 使用永久表代替
  • 使用UNION语句模仿临时表

每一个选项都常常能用来帮助消除你TSQL代码里的临时表。 

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

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

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

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

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

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

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

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

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

存储过程为开发人员提供了很多好处,包括:

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

作为首要的常规,所有的TSQL代码都应该通过存储过程调用。 

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

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

SET NOCOUNT ON

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

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

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

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

如果SQLServerMaster数据库里不能找到存储过程,那么接下来会将存储过程的拥有者作为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-LIBDAORDOADO还是.NET

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

应用程序使用ODBC还是OLEDBSQLServer通信?

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

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

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

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

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

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

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

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

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

传给SQLServerTSQL代码是最优化的还是普通的SQL

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

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

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

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

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

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

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

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

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


SQLServer作业监控列表 

你的答案 

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

 

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

 

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

 

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

 

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

 

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

 

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

 


在上表输入你的结果。 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值